1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "base/functional/bind.h"
8 #include "components/permissions/bluetooth_chooser_controller.h"
9 #include "components/permissions/mock_chooser_controller_view.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 namespace permissions {
15 class TestBluetoothChooserController : public BluetoothChooserController {
17 TestBluetoothChooserController(
18 content::RenderFrameHost* owner,
19 const content::BluetoothChooser::EventHandler& event_handler,
21 : BluetoothChooserController(owner, event_handler, title) {}
23 TestBluetoothChooserController(const TestBluetoothChooserController&) =
25 TestBluetoothChooserController& operator=(
26 const TestBluetoothChooserController&) = delete;
28 void OpenAdapterOffHelpUrl() const override {}
29 void OpenPermissionPreferences() const override {}
30 void OpenHelpCenterUrl() const override {}
33 using testing::NiceMock;
35 class BluetoothChooserControllerTest : public testing::Test {
37 BluetoothChooserControllerTest()
38 : bluetooth_chooser_controller_(
41 &BluetoothChooserControllerTest::OnBluetoothChooserEvent,
42 base::Unretained(this)),
44 bluetooth_chooser_controller_.set_view(&mock_bluetooth_chooser_view_);
47 BluetoothChooserControllerTest(const BluetoothChooserControllerTest&) =
49 BluetoothChooserControllerTest& operator=(
50 const BluetoothChooserControllerTest&) = delete;
53 void OnBluetoothChooserEvent(content::BluetoothChooserEvent event,
54 const std::string& device_id) {
56 last_device_id_ = device_id;
59 TestBluetoothChooserController bluetooth_chooser_controller_;
60 NiceMock<MockChooserControllerView> mock_bluetooth_chooser_view_;
61 content::BluetoothChooserEvent last_event_;
62 std::string last_device_id_;
65 class BluetoothChooserControllerWithDevicesAddedTest
66 : public BluetoothChooserControllerTest {
68 BluetoothChooserControllerWithDevicesAddedTest() {
69 bluetooth_chooser_controller_.AddOrUpdateDevice(
70 "id_a", false /* should_update_name */, u"a",
71 true /* is_gatt_connected */, true /* is_paired */,
72 -1 /* signal_strength_level */);
73 bluetooth_chooser_controller_.AddOrUpdateDevice(
74 "id_b", false /* should_update_name */, u"b",
75 true /* is_gatt_connected */, true /* is_paired */,
76 0 /* signal_strength_level */);
77 bluetooth_chooser_controller_.AddOrUpdateDevice(
78 "id_c", false /* should_update_name */, u"c",
79 true /* is_gatt_connected */, true /* is_paired */,
80 1 /* signal_strength_level */);
84 TEST_F(BluetoothChooserControllerTest, AddDevice) {
85 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionAdded(0)).Times(1);
86 bluetooth_chooser_controller_.AddOrUpdateDevice(
87 "id_a", false /* should_update_name */, u"a",
88 true /* is_gatt_connected */, true /* is_paired */,
89 -1 /* signal_strength_level */);
90 EXPECT_EQ(1u, bluetooth_chooser_controller_.NumOptions());
91 EXPECT_EQ(u"a", bluetooth_chooser_controller_.GetOption(0));
92 EXPECT_EQ(-1, bluetooth_chooser_controller_.GetSignalStrengthLevel(0));
93 EXPECT_TRUE(bluetooth_chooser_controller_.IsConnected(0));
94 EXPECT_TRUE(bluetooth_chooser_controller_.IsPaired(0));
95 testing::Mock::VerifyAndClearExpectations(&mock_bluetooth_chooser_view_);
97 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionAdded(1)).Times(1);
98 bluetooth_chooser_controller_.AddOrUpdateDevice(
99 "id_b", false /* should_update_name */, u"b",
100 true /* is_gatt_connected */, true /* is_paired */,
101 0 /* signal_strength_level */);
102 EXPECT_EQ(2u, bluetooth_chooser_controller_.NumOptions());
103 EXPECT_EQ(u"b", bluetooth_chooser_controller_.GetOption(1));
104 EXPECT_EQ(0, bluetooth_chooser_controller_.GetSignalStrengthLevel(1));
105 testing::Mock::VerifyAndClearExpectations(&mock_bluetooth_chooser_view_);
107 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionAdded(2)).Times(1);
108 bluetooth_chooser_controller_.AddOrUpdateDevice(
109 "id_c", false /* should_update_name */, u"c",
110 true /* is_gatt_connected */, true /* is_paired */,
111 1 /* signal_strength_level */);
112 EXPECT_EQ(3u, bluetooth_chooser_controller_.NumOptions());
113 EXPECT_EQ(u"c", bluetooth_chooser_controller_.GetOption(2));
114 EXPECT_EQ(1, bluetooth_chooser_controller_.GetSignalStrengthLevel(2));
117 TEST_F(BluetoothChooserControllerTest, RemoveDevice) {
118 bluetooth_chooser_controller_.AddOrUpdateDevice(
119 "id_a", false /* should_update_name */, u"a",
120 true /* is_gatt_connected */, true /* is_paired */,
121 -1 /* signal_strength_level */);
122 bluetooth_chooser_controller_.AddOrUpdateDevice(
123 "id_b", false /* should_update_name */, u"b",
124 true /* is_gatt_connected */, true /* is_paired */,
125 0 /* signal_strength_level */);
126 bluetooth_chooser_controller_.AddOrUpdateDevice(
127 "id_c", false /* should_update_name */, u"c",
128 true /* is_gatt_connected */, true /* is_paired */,
129 1 /* signal_strength_level */);
131 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionRemoved(1)).Times(1);
132 bluetooth_chooser_controller_.RemoveDevice("id_b");
133 EXPECT_EQ(2u, bluetooth_chooser_controller_.NumOptions());
134 EXPECT_EQ(u"a", bluetooth_chooser_controller_.GetOption(0));
135 EXPECT_EQ(u"c", bluetooth_chooser_controller_.GetOption(1));
136 testing::Mock::VerifyAndClearExpectations(&mock_bluetooth_chooser_view_);
138 // Remove a non-existent device, the number of devices should not change.
139 bluetooth_chooser_controller_.RemoveDevice("non-existent");
140 EXPECT_EQ(2u, bluetooth_chooser_controller_.NumOptions());
141 EXPECT_EQ(u"a", bluetooth_chooser_controller_.GetOption(0));
142 EXPECT_EQ(u"c", bluetooth_chooser_controller_.GetOption(1));
144 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionRemoved(0)).Times(1);
145 bluetooth_chooser_controller_.RemoveDevice("id_a");
146 EXPECT_EQ(1u, bluetooth_chooser_controller_.NumOptions());
147 EXPECT_EQ(u"c", bluetooth_chooser_controller_.GetOption(0));
148 testing::Mock::VerifyAndClearExpectations(&mock_bluetooth_chooser_view_);
150 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionRemoved(0)).Times(1);
151 bluetooth_chooser_controller_.RemoveDevice("id_c");
152 EXPECT_EQ(0u, bluetooth_chooser_controller_.NumOptions());
155 TEST_F(BluetoothChooserControllerTest, MultipleDevicesWithSameNameShowIds) {
156 bluetooth_chooser_controller_.AddOrUpdateDevice(
157 "id_a_1", false /* should_update_name */, u"a",
158 true /* is_gatt_connected */, true /* is_paired */,
159 -1 /* signal_strength_level */);
160 EXPECT_EQ(u"a", bluetooth_chooser_controller_.GetOption(0));
162 bluetooth_chooser_controller_.AddOrUpdateDevice(
163 "id_b", false /* should_update_name */, u"b",
164 true /* is_gatt_connected */, true /* is_paired */,
165 0 /* signal_strength_level */);
166 bluetooth_chooser_controller_.AddOrUpdateDevice(
167 "id_a_2", false /* should_update_name */, u"a",
168 true /* is_gatt_connected */, true /* is_paired */,
169 1 /* signal_strength_level */);
170 EXPECT_EQ(u"a (id_a_1)", bluetooth_chooser_controller_.GetOption(0));
171 EXPECT_EQ(u"b", bluetooth_chooser_controller_.GetOption(1));
172 EXPECT_EQ(u"a (id_a_2)", bluetooth_chooser_controller_.GetOption(2));
174 bluetooth_chooser_controller_.RemoveDevice("id_a_1");
175 EXPECT_EQ(u"b", bluetooth_chooser_controller_.GetOption(0));
176 EXPECT_EQ(u"a", bluetooth_chooser_controller_.GetOption(1));
179 TEST_F(BluetoothChooserControllerTest, UpdateDeviceName) {
180 bluetooth_chooser_controller_.AddOrUpdateDevice(
181 "id_a", false /* should_update_name */, u"a",
182 true /* is_gatt_connected */, true /* is_paired */,
183 -1 /* signal_strength_level */);
184 EXPECT_EQ(u"a", bluetooth_chooser_controller_.GetOption(0));
186 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionUpdated(0)).Times(1);
187 bluetooth_chooser_controller_.AddOrUpdateDevice(
188 "id_a", false /* should_update_name */, u"aa",
189 true /* is_gatt_connected */, true /* is_paired */,
190 -1 /* signal_strength_level */);
191 // The name is still "a" since |should_update_name| is false.
192 EXPECT_EQ(u"a", bluetooth_chooser_controller_.GetOption(0));
193 testing::Mock::VerifyAndClearExpectations(&mock_bluetooth_chooser_view_);
195 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionUpdated(0)).Times(1);
196 bluetooth_chooser_controller_.AddOrUpdateDevice(
197 "id_a", true /* should_update_name */, u"aa",
198 true /* is_gatt_connected */, true /* is_paired */,
199 -1 /* signal_strength_level */);
200 EXPECT_EQ(1u, bluetooth_chooser_controller_.NumOptions());
201 EXPECT_EQ(u"aa", bluetooth_chooser_controller_.GetOption(0));
203 bluetooth_chooser_controller_.RemoveDevice("id_a");
204 EXPECT_EQ(0u, bluetooth_chooser_controller_.NumOptions());
207 TEST_F(BluetoothChooserControllerTest, UpdateDeviceSignalStrengthLevel) {
208 bluetooth_chooser_controller_.AddOrUpdateDevice(
209 "id_a", false /* should_update_name */, u"a",
210 true /* is_gatt_connected */, true /* is_paired */,
211 -1 /* signal_strength_level */);
212 EXPECT_EQ(-1, bluetooth_chooser_controller_.GetSignalStrengthLevel(0));
214 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionUpdated(0)).Times(1);
215 bluetooth_chooser_controller_.AddOrUpdateDevice(
216 "id_a", false /* should_update_name */, u"a",
217 true /* is_gatt_connected */, true /* is_paired */,
218 1 /* signal_strength_level */);
219 EXPECT_EQ(1, bluetooth_chooser_controller_.GetSignalStrengthLevel(0));
220 testing::Mock::VerifyAndClearExpectations(&mock_bluetooth_chooser_view_);
222 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionUpdated(0)).Times(1);
223 // When Bluetooth device scanning stops, an update is sent and the signal
224 // strength level is -1, and in this case, should still use the previously
225 // stored signal strength level. So here the signal strength level is
227 bluetooth_chooser_controller_.AddOrUpdateDevice(
228 "id_a", false /* should_update_name */, u"a",
229 true /* is_gatt_connected */, true /* is_paired */,
230 -1 /* signal_strength_level */);
231 EXPECT_EQ(1, bluetooth_chooser_controller_.GetSignalStrengthLevel(0));
234 TEST_F(BluetoothChooserControllerTest, UpdateConnectedStatus) {
235 bluetooth_chooser_controller_.AddOrUpdateDevice(
236 "id_a", false /* should_update_name */, u"a",
237 false /* is_gatt_connected */, false /* is_paired */,
238 1 /* signal_strength_level */);
239 EXPECT_FALSE(bluetooth_chooser_controller_.IsConnected(0));
241 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionUpdated(0)).Times(1);
242 bluetooth_chooser_controller_.AddOrUpdateDevice(
243 "id_a", false /* should_update_name */, u"a",
244 true /* is_gatt_connected */, false /* is_paired */,
245 -1 /* signal_strength_level */);
246 EXPECT_TRUE(bluetooth_chooser_controller_.IsConnected(0));
249 TEST_F(BluetoothChooserControllerTest, UpdatePairedStatus) {
250 bluetooth_chooser_controller_.AddOrUpdateDevice(
251 "id_a", false /* should_update_name */, u"a",
252 true /* is_gatt_connected */, false /* is_paired */,
253 -1 /* signal_strength_level */);
254 EXPECT_FALSE(bluetooth_chooser_controller_.IsPaired(0));
256 EXPECT_CALL(mock_bluetooth_chooser_view_, OnOptionUpdated(0)).Times(1);
257 bluetooth_chooser_controller_.AddOrUpdateDevice(
258 "id_a", false /* should_update_name */, u"a",
259 true /* is_gatt_connected */, true /* is_paired */,
260 -1 /* signal_strength_level */);
261 EXPECT_TRUE(bluetooth_chooser_controller_.IsPaired(0));
264 TEST_F(BluetoothChooserControllerWithDevicesAddedTest,
265 BluetoothAdapterTurnedOff) {
266 EXPECT_CALL(mock_bluetooth_chooser_view_,
267 OnAdapterEnabledChanged(/*enabled=*/false))
269 bluetooth_chooser_controller_.OnAdapterPresenceChanged(
270 content::BluetoothChooser::AdapterPresence::POWERED_OFF);
271 EXPECT_EQ(0u, bluetooth_chooser_controller_.NumOptions());
274 TEST_F(BluetoothChooserControllerWithDevicesAddedTest,
275 BluetoothAdapterTurnedOn) {
276 EXPECT_CALL(mock_bluetooth_chooser_view_,
277 OnAdapterEnabledChanged(/*enabled=*/true))
279 bluetooth_chooser_controller_.OnAdapterPresenceChanged(
280 content::BluetoothChooser::AdapterPresence::POWERED_ON);
281 EXPECT_EQ(0u, bluetooth_chooser_controller_.NumOptions());
284 TEST_F(BluetoothChooserControllerWithDevicesAddedTest, DiscoveringState) {
285 EXPECT_CALL(mock_bluetooth_chooser_view_,
286 OnRefreshStateChanged(/*refreshing=*/true))
288 bluetooth_chooser_controller_.OnDiscoveryStateChanged(
289 content::BluetoothChooser::DiscoveryState::DISCOVERING);
292 TEST_F(BluetoothChooserControllerWithDevicesAddedTest, IdleState) {
293 EXPECT_CALL(mock_bluetooth_chooser_view_,
294 OnRefreshStateChanged(/*refreshing=*/false))
296 bluetooth_chooser_controller_.OnDiscoveryStateChanged(
297 content::BluetoothChooser::DiscoveryState::IDLE);
300 TEST_F(BluetoothChooserControllerWithDevicesAddedTest, FailedToStartState) {
301 EXPECT_CALL(mock_bluetooth_chooser_view_,
302 OnRefreshStateChanged(/*refreshing=*/false))
304 bluetooth_chooser_controller_.OnDiscoveryStateChanged(
305 content::BluetoothChooser::DiscoveryState::FAILED_TO_START);
308 TEST_F(BluetoothChooserControllerWithDevicesAddedTest, RefreshOptions) {
309 bluetooth_chooser_controller_.RefreshOptions();
310 EXPECT_EQ(0u, bluetooth_chooser_controller_.NumOptions());
311 EXPECT_EQ(content::BluetoothChooserEvent::RESCAN, last_event_);
312 EXPECT_EQ(std::string(), last_device_id_);
315 TEST_F(BluetoothChooserControllerWithDevicesAddedTest,
316 SelectingOneDeviceShouldCallEventHandler) {
317 std::vector<size_t> indices{0};
318 bluetooth_chooser_controller_.Select(indices);
319 EXPECT_EQ(content::BluetoothChooserEvent::SELECTED, last_event_);
320 EXPECT_EQ("id_a", last_device_id_);
323 TEST_F(BluetoothChooserControllerWithDevicesAddedTest,
324 CancelShouldCallEventHandler) {
325 bluetooth_chooser_controller_.Cancel();
326 EXPECT_EQ(content::BluetoothChooserEvent::CANCELLED, last_event_);
327 EXPECT_EQ(std::string(), last_device_id_);
330 TEST_F(BluetoothChooserControllerWithDevicesAddedTest,
331 CloseShouldCallEventHandler) {
332 bluetooth_chooser_controller_.Close();
333 EXPECT_EQ(content::BluetoothChooserEvent::CANCELLED, last_event_);
334 EXPECT_EQ(std::string(), last_device_id_);
337 } // namespace permissions