1 | /* |
2 | * SPDX-FileCopyrightText: 2014-2015 David Rosca <nowrep@gmail.com> |
3 | * |
4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
5 | */ |
6 | |
7 | #include "devicetest.h" |
8 | #include "autotests.h" |
9 | #include "initmanagerjob.h" |
10 | #include "pendingcall.h" |
11 | |
12 | #include <QSignalSpy> |
13 | #include <QTest> |
14 | |
15 | namespace BluezQt |
16 | { |
17 | extern void bluezqt_initFakeBluezTestRun(); |
18 | } |
19 | |
20 | using namespace BluezQt; |
21 | |
22 | DeviceTest::DeviceTest() |
23 | : m_manager(nullptr) |
24 | { |
25 | Autotests::registerMetatypes(); |
26 | } |
27 | |
28 | void DeviceTest::initTestCase() |
29 | { |
30 | QDBusConnection connection = QDBusConnection::sessionBus(); |
31 | QString service = QStringLiteral("org.kde.bluezqt.fakebluez" ); |
32 | |
33 | bluezqt_initFakeBluezTestRun(); |
34 | |
35 | FakeBluez::start(); |
36 | FakeBluez::runTest(QStringLiteral("bluez-standard" )); |
37 | |
38 | // Create adapters |
39 | QDBusObjectPath adapter1 = QDBusObjectPath(QStringLiteral("/org/bluez/hci0" )); |
40 | QVariantMap adapterProps; |
41 | adapterProps[QStringLiteral("Path" )] = QVariant::fromValue(adapter1); |
42 | adapterProps[QStringLiteral("Address" )] = QStringLiteral("1C:E5:C3:BC:94:7E" ); |
43 | adapterProps[QStringLiteral("Name" )] = QStringLiteral("TestAdapter" ); |
44 | FakeBluez::runAction(QStringLiteral("devicemanager" ), QStringLiteral("create-adapter" ), adapterProps); |
45 | |
46 | QDBusObjectPath adapter2 = QDBusObjectPath(QStringLiteral("/org/bluez/hci1" )); |
47 | adapterProps[QStringLiteral("Path" )] = QVariant::fromValue(adapter2); |
48 | adapterProps[QStringLiteral("Address" )] = QStringLiteral("2E:3A:C3:BC:85:7C" ); |
49 | adapterProps[QStringLiteral("Name" )] = QStringLiteral("TestAdapter2" ); |
50 | FakeBluez::runAction(QStringLiteral("devicemanager" ), QStringLiteral("create-adapter" ), adapterProps); |
51 | |
52 | // Create devices |
53 | QVariantMap deviceProps; |
54 | deviceProps[QStringLiteral("Path" )] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75" )); |
55 | deviceProps[QStringLiteral("Adapter" )] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0" )); |
56 | deviceProps[QStringLiteral("Address" )] = QStringLiteral("40:79:6A:0C:39:75" ); |
57 | deviceProps[QStringLiteral("Name" )] = QStringLiteral("TestDevice" ); |
58 | deviceProps[QStringLiteral("Alias" )] = QStringLiteral("TestAlias" ); |
59 | deviceProps[QStringLiteral("Icon" )] = QStringLiteral("phone" ); |
60 | deviceProps[QStringLiteral("Class" )] = QVariant::fromValue(quint32(101)); |
61 | deviceProps[QStringLiteral("Appearance" )] = QVariant::fromValue(quint16(25)); |
62 | deviceProps[QStringLiteral("UUIDs" )] = QStringList(); |
63 | deviceProps[QStringLiteral("Paired" )] = false; |
64 | deviceProps[QStringLiteral("Connected" )] = false; |
65 | deviceProps[QStringLiteral("Trusted" )] = false; |
66 | deviceProps[QStringLiteral("Blocked" )] = false; |
67 | deviceProps[QStringLiteral("LegacyPairing" )] = false; |
68 | deviceProps[QStringLiteral("RSSI" )] = QVariant::fromValue(qint16(20)); |
69 | deviceProps[QStringLiteral("Modalias" )] = QStringLiteral("bluetooth:v001Dp1200d1236" ); |
70 | FakeBluez::runAction(QStringLiteral("devicemanager" ), QStringLiteral("create-device" ), deviceProps); |
71 | |
72 | deviceProps[QStringLiteral("Path" )] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75" )); |
73 | deviceProps[QStringLiteral("Adapter" )] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1" )); |
74 | deviceProps[QStringLiteral("Address" )] = QStringLiteral("50:79:6A:0C:39:75" ); |
75 | deviceProps[QStringLiteral("Name" )] = QStringLiteral("TestDevice2" ); |
76 | deviceProps[QStringLiteral("Alias" )] = QStringLiteral("TestAlias2" ); |
77 | deviceProps[QStringLiteral("Icon" )] = QStringLiteral("joypad" ); |
78 | deviceProps[QStringLiteral("Class" )] = QVariant::fromValue(quint32(201)); |
79 | deviceProps[QStringLiteral("Appearance" )] = QVariant::fromValue(quint16(32)); |
80 | deviceProps[QStringLiteral("UUIDs" )] = QStringList(); |
81 | deviceProps[QStringLiteral("Paired" )] = true; |
82 | deviceProps[QStringLiteral("Connected" )] = false; |
83 | deviceProps[QStringLiteral("Trusted" )] = true; |
84 | deviceProps[QStringLiteral("Blocked" )] = false; |
85 | deviceProps[QStringLiteral("LegacyPairing" )] = false; |
86 | deviceProps[QStringLiteral("RSSI" )] = QVariant::fromValue(qint16(-15)); |
87 | deviceProps[QStringLiteral("Modalias" )] = QStringLiteral("bluetooth:v001Dp1100d1236" ); |
88 | FakeBluez::runAction(QStringLiteral("devicemanager" ), QStringLiteral("create-device" ), deviceProps); |
89 | |
90 | m_manager = new Manager(); |
91 | InitManagerJob *initJob = m_manager->init(); |
92 | initJob->exec(); |
93 | QVERIFY(!initJob->error()); |
94 | |
95 | for (const AdapterPtr &adapter : m_manager->adapters()) { |
96 | QVERIFY(!adapter->ubi().isEmpty()); |
97 | |
98 | for (const DevicePtr &device : adapter->devices()) { |
99 | QVERIFY(!device->ubi().isEmpty()); |
100 | |
101 | DeviceUnit u; |
102 | u.device = device; |
103 | u.dbusDevice = new org::bluez::Device1(service, device->ubi(), connection, this); |
104 | u.dbusProperties = new org::freedesktop::DBus::Properties(service, device->ubi(), connection, this); |
105 | m_units.append(u); |
106 | } |
107 | } |
108 | |
109 | QCOMPARE(m_manager->adapters().count(), 2); |
110 | QCOMPARE(m_manager->devices().count(), 2); |
111 | } |
112 | |
113 | void DeviceTest::cleanupTestCase() |
114 | { |
115 | for (const DeviceUnit &unit : m_units) { |
116 | delete unit.dbusDevice; |
117 | delete unit.dbusProperties; |
118 | } |
119 | |
120 | delete m_manager; |
121 | |
122 | FakeBluez::stop(); |
123 | } |
124 | |
125 | static void compareUuids(const QStringList &actual, const QStringList &expected) |
126 | { |
127 | QCOMPARE(actual.size(), expected.size()); |
128 | |
129 | for (int i = 0; i < actual.size(); ++i) { |
130 | QCOMPARE(actual.at(i).toUpper(), expected.at(i).toUpper()); |
131 | } |
132 | } |
133 | |
134 | void DeviceTest::getPropertiesTest() |
135 | { |
136 | for (const DeviceUnit &unit : m_units) { |
137 | QCOMPARE(unit.device->ubi(), unit.dbusDevice->path()); |
138 | QCOMPARE(unit.device->address(), unit.dbusDevice->address()); |
139 | QCOMPARE(unit.device->name(), unit.dbusDevice->alias()); |
140 | QCOMPARE(unit.device->remoteName(), unit.dbusDevice->name()); |
141 | QCOMPARE(unit.device->deviceClass(), unit.dbusDevice->deviceClass()); |
142 | QCOMPARE(unit.device->appearance(), unit.dbusDevice->appearance()); |
143 | QCOMPARE(unit.device->icon(), deviceIcon(unit.dbusDevice)); |
144 | QCOMPARE(unit.device->isPaired(), unit.dbusDevice->paired()); |
145 | QCOMPARE(unit.device->isTrusted(), unit.dbusDevice->trusted()); |
146 | QCOMPARE(unit.device->isBlocked(), unit.dbusDevice->blocked()); |
147 | QCOMPARE(unit.device->hasLegacyPairing(), unit.dbusDevice->legacyPairing()); |
148 | QCOMPARE(unit.device->rssi(), deviceRssi(unit.dbusDevice)); |
149 | QCOMPARE(unit.device->isConnected(), unit.dbusDevice->connected()); |
150 | QCOMPARE(unit.device->modalias(), unit.dbusDevice->modalias()); |
151 | QCOMPARE(unit.device->adapter()->ubi(), unit.dbusDevice->adapter().path()); |
152 | |
153 | compareUuids(unit.device->uuids(), unit.dbusDevice->uUIDs()); |
154 | } |
155 | } |
156 | |
157 | void DeviceTest::setAliasTest() |
158 | { |
159 | for (const DeviceUnit &unit : m_units) { |
160 | QSignalSpy deviceSpy(unit.device.data(), SIGNAL(nameChanged(QString))); |
161 | QSignalSpy dbusSpy(unit.dbusProperties, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList))); |
162 | |
163 | QString value = unit.device->name() + QLatin1String("_tst_alias" ); |
164 | |
165 | unit.device->setName(value); |
166 | QTRY_COMPARE(deviceSpy.count(), 1); |
167 | |
168 | QList<QVariant> arguments = deviceSpy.takeFirst(); |
169 | QCOMPARE(arguments.at(0).toString(), value); |
170 | Autotests::verifyPropertiesChangedSignal(dbusSpy, QStringLiteral("Alias" ), value); |
171 | |
172 | QCOMPARE(unit.device->name(), value); |
173 | QCOMPARE(unit.dbusDevice->alias(), value); |
174 | } |
175 | } |
176 | |
177 | void DeviceTest::setTrustedTest() |
178 | { |
179 | for (const DeviceUnit &unit : m_units) { |
180 | QSignalSpy deviceSpy(unit.device.data(), SIGNAL(trustedChanged(bool))); |
181 | QSignalSpy dbusSpy(unit.dbusProperties, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList))); |
182 | |
183 | bool value = !unit.device->isTrusted(); |
184 | |
185 | unit.device->setTrusted(value); |
186 | QTRY_COMPARE(deviceSpy.count(), 1); |
187 | |
188 | QList<QVariant> arguments = deviceSpy.takeFirst(); |
189 | QCOMPARE(arguments.at(0).toBool(), value); |
190 | Autotests::verifyPropertiesChangedSignal(dbusSpy, QStringLiteral("Trusted" ), value); |
191 | |
192 | QCOMPARE(unit.device->isTrusted(), value); |
193 | QCOMPARE(unit.dbusDevice->trusted(), value); |
194 | } |
195 | } |
196 | |
197 | void DeviceTest::setBlockedTest() |
198 | { |
199 | for (const DeviceUnit &unit : m_units) { |
200 | QSignalSpy deviceSpy(unit.device.data(), SIGNAL(blockedChanged(bool))); |
201 | QSignalSpy dbusSpy(unit.dbusProperties, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList))); |
202 | |
203 | bool value = !unit.device->isBlocked(); |
204 | |
205 | unit.device->setBlocked(value); |
206 | QTRY_COMPARE(deviceSpy.count(), 1); |
207 | |
208 | QList<QVariant> arguments = deviceSpy.takeFirst(); |
209 | QCOMPARE(arguments.at(0).toBool(), value); |
210 | Autotests::verifyPropertiesChangedSignal(dbusSpy, QStringLiteral("Blocked" ), value); |
211 | |
212 | QCOMPARE(unit.device->isBlocked(), value); |
213 | QCOMPARE(unit.dbusDevice->blocked(), value); |
214 | } |
215 | } |
216 | |
217 | void DeviceTest::deviceRemovedTest() |
218 | { |
219 | for (const DeviceUnit &unit : m_units) { |
220 | QSignalSpy managerSpy(m_manager, SIGNAL(deviceRemoved(DevicePtr))); |
221 | QSignalSpy adapterSpy(unit.device->adapter().data(), SIGNAL(deviceRemoved(DevicePtr))); |
222 | QSignalSpy deviceSpy(unit.device.data(), SIGNAL(deviceRemoved(DevicePtr))); |
223 | |
224 | QVariantMap properties; |
225 | properties[QStringLiteral("Path" )] = QVariant::fromValue(QDBusObjectPath(unit.device->ubi())); |
226 | FakeBluez::runAction(QStringLiteral("devicemanager" ), QStringLiteral("remove-device" ), properties); |
227 | |
228 | QTRY_COMPARE(managerSpy.count(), 1); |
229 | QTRY_COMPARE(adapterSpy.count(), 1); |
230 | QTRY_COMPARE(deviceSpy.count(), 1); |
231 | |
232 | QCOMPARE(managerSpy.at(0).at(0).value<DevicePtr>(), unit.device); |
233 | QCOMPARE(adapterSpy.at(0).at(0).value<DevicePtr>(), unit.device); |
234 | QCOMPARE(deviceSpy.at(0).at(0).value<DevicePtr>(), unit.device); |
235 | } |
236 | } |
237 | |
238 | QString DeviceTest::deviceIcon(org::bluez::Device1 *device) const |
239 | { |
240 | quint32 classNum = device->deviceClass(); |
241 | switch ((classNum & 0x1f00) >> 8) { |
242 | case 0x04: |
243 | switch ((classNum & 0xfc) >> 2) { |
244 | case 0x01: |
245 | case 0x02: |
246 | return QStringLiteral("audio-headset" ); |
247 | case 0x06: |
248 | return QStringLiteral("audio-headphones" ); |
249 | } |
250 | } |
251 | return device->icon(); |
252 | } |
253 | |
254 | qint16 DeviceTest::(org::bluez::Device1 *device) const |
255 | { |
256 | qint16 = device->rSSI(); |
257 | if (!rssi) { |
258 | rssi = -32768; |
259 | } |
260 | return rssi; |
261 | } |
262 | |
263 | QTEST_MAIN(DeviceTest) |
264 | |
265 | #include "moc_devicetest.cpp" |
266 | |