File indexing completed on 2024-03-24 15:24:16

0001 /*
0002  * SPDX-FileCopyrightText: 2014-2015 David Rosca <nowrep@gmail.com>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005  */
0006 
0007 #include "devicetest.h"
0008 #include "autotests.h"
0009 #include "initmanagerjob.h"
0010 #include "pendingcall.h"
0011 
0012 #include <QSignalSpy>
0013 #include <QTest>
0014 
0015 namespace BluezQt
0016 {
0017 extern void bluezqt_initFakeBluezTestRun();
0018 }
0019 
0020 using namespace BluezQt;
0021 
0022 DeviceTest::DeviceTest()
0023     : m_manager(nullptr)
0024 {
0025     Autotests::registerMetatypes();
0026 }
0027 
0028 void DeviceTest::initTestCase()
0029 {
0030     QDBusConnection connection = QDBusConnection::sessionBus();
0031     QString service = QStringLiteral("org.kde.bluezqt.fakebluez");
0032 
0033     bluezqt_initFakeBluezTestRun();
0034 
0035     FakeBluez::start();
0036     FakeBluez::runTest(QStringLiteral("bluez-standard"));
0037 
0038     // Create adapters
0039     QDBusObjectPath adapter1 = QDBusObjectPath(QStringLiteral("/org/bluez/hci0"));
0040     QVariantMap adapterProps;
0041     adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter1);
0042     adapterProps[QStringLiteral("Address")] = QStringLiteral("1C:E5:C3:BC:94:7E");
0043     adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter");
0044     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps);
0045 
0046     QDBusObjectPath adapter2 = QDBusObjectPath(QStringLiteral("/org/bluez/hci1"));
0047     adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter2);
0048     adapterProps[QStringLiteral("Address")] = QStringLiteral("2E:3A:C3:BC:85:7C");
0049     adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter2");
0050     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps);
0051 
0052     // Create devices
0053     QVariantMap deviceProps;
0054     deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75"));
0055     deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0"));
0056     deviceProps[QStringLiteral("Address")] = QStringLiteral("40:79:6A:0C:39:75");
0057     deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice");
0058     deviceProps[QStringLiteral("Alias")] = QStringLiteral("TestAlias");
0059     deviceProps[QStringLiteral("Icon")] = QStringLiteral("phone");
0060     deviceProps[QStringLiteral("Class")] = QVariant::fromValue(quint32(101));
0061     deviceProps[QStringLiteral("Appearance")] = QVariant::fromValue(quint16(25));
0062     deviceProps[QStringLiteral("UUIDs")] = QStringList();
0063     deviceProps[QStringLiteral("Paired")] = false;
0064     deviceProps[QStringLiteral("Connected")] = false;
0065     deviceProps[QStringLiteral("Trusted")] = false;
0066     deviceProps[QStringLiteral("Blocked")] = false;
0067     deviceProps[QStringLiteral("LegacyPairing")] = false;
0068     deviceProps[QStringLiteral("RSSI")] = QVariant::fromValue(qint16(20));
0069     deviceProps[QStringLiteral("Modalias")] = QStringLiteral("bluetooth:v001Dp1200d1236");
0070     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps);
0071 
0072     deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75"));
0073     deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1"));
0074     deviceProps[QStringLiteral("Address")] = QStringLiteral("50:79:6A:0C:39:75");
0075     deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice2");
0076     deviceProps[QStringLiteral("Alias")] = QStringLiteral("TestAlias2");
0077     deviceProps[QStringLiteral("Icon")] = QStringLiteral("joypad");
0078     deviceProps[QStringLiteral("Class")] = QVariant::fromValue(quint32(201));
0079     deviceProps[QStringLiteral("Appearance")] = QVariant::fromValue(quint16(32));
0080     deviceProps[QStringLiteral("UUIDs")] = QStringList();
0081     deviceProps[QStringLiteral("Paired")] = true;
0082     deviceProps[QStringLiteral("Connected")] = false;
0083     deviceProps[QStringLiteral("Trusted")] = true;
0084     deviceProps[QStringLiteral("Blocked")] = false;
0085     deviceProps[QStringLiteral("LegacyPairing")] = false;
0086     deviceProps[QStringLiteral("RSSI")] = QVariant::fromValue(qint16(-15));
0087     deviceProps[QStringLiteral("Modalias")] = QStringLiteral("bluetooth:v001Dp1100d1236");
0088     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps);
0089 
0090     m_manager = new Manager();
0091     InitManagerJob *initJob = m_manager->init();
0092     initJob->exec();
0093     QVERIFY(!initJob->error());
0094 
0095     for (const AdapterPtr &adapter : m_manager->adapters()) {
0096         QVERIFY(!adapter->ubi().isEmpty());
0097 
0098         for (const DevicePtr &device : adapter->devices()) {
0099             QVERIFY(!device->ubi().isEmpty());
0100 
0101             DeviceUnit u;
0102             u.device = device;
0103             u.dbusDevice = new org::bluez::Device1(service, device->ubi(), connection, this);
0104             u.dbusProperties = new org::freedesktop::DBus::Properties(service, device->ubi(), connection, this);
0105             m_units.append(u);
0106         }
0107     }
0108 
0109     QCOMPARE(m_manager->adapters().count(), 2);
0110     QCOMPARE(m_manager->devices().count(), 2);
0111 }
0112 
0113 void DeviceTest::cleanupTestCase()
0114 {
0115     for (const DeviceUnit &unit : m_units) {
0116         delete unit.dbusDevice;
0117         delete unit.dbusProperties;
0118     }
0119 
0120     delete m_manager;
0121 
0122     FakeBluez::stop();
0123 }
0124 
0125 static void compareUuids(const QStringList &actual, const QStringList &expected)
0126 {
0127     QCOMPARE(actual.size(), expected.size());
0128 
0129     for (int i = 0; i < actual.size(); ++i) {
0130         QCOMPARE(actual.at(i).toUpper(), expected.at(i).toUpper());
0131     }
0132 }
0133 
0134 void DeviceTest::getPropertiesTest()
0135 {
0136     for (const DeviceUnit &unit : m_units) {
0137         QCOMPARE(unit.device->ubi(), unit.dbusDevice->path());
0138         QCOMPARE(unit.device->address(), unit.dbusDevice->address());
0139         QCOMPARE(unit.device->name(), unit.dbusDevice->alias());
0140         QCOMPARE(unit.device->remoteName(), unit.dbusDevice->name());
0141         QCOMPARE(unit.device->deviceClass(), unit.dbusDevice->deviceClass());
0142         QCOMPARE(unit.device->appearance(), unit.dbusDevice->appearance());
0143         QCOMPARE(unit.device->icon(), deviceIcon(unit.dbusDevice));
0144         QCOMPARE(unit.device->isPaired(), unit.dbusDevice->paired());
0145         QCOMPARE(unit.device->isTrusted(), unit.dbusDevice->trusted());
0146         QCOMPARE(unit.device->isBlocked(), unit.dbusDevice->blocked());
0147         QCOMPARE(unit.device->hasLegacyPairing(), unit.dbusDevice->legacyPairing());
0148         QCOMPARE(unit.device->rssi(), deviceRssi(unit.dbusDevice));
0149         QCOMPARE(unit.device->isConnected(), unit.dbusDevice->connected());
0150         QCOMPARE(unit.device->modalias(), unit.dbusDevice->modalias());
0151         QCOMPARE(unit.device->adapter()->ubi(), unit.dbusDevice->adapter().path());
0152 
0153         compareUuids(unit.device->uuids(), unit.dbusDevice->uUIDs());
0154     }
0155 }
0156 
0157 void DeviceTest::setAliasTest()
0158 {
0159     for (const DeviceUnit &unit : m_units) {
0160         QSignalSpy deviceSpy(unit.device.data(), SIGNAL(nameChanged(QString)));
0161         QSignalSpy dbusSpy(unit.dbusProperties, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList)));
0162 
0163         QString value = unit.device->name() + QLatin1String("_tst_alias");
0164 
0165         unit.device->setName(value);
0166         QTRY_COMPARE(deviceSpy.count(), 1);
0167 
0168         QList<QVariant> arguments = deviceSpy.takeFirst();
0169         QCOMPARE(arguments.at(0).toString(), value);
0170         Autotests::verifyPropertiesChangedSignal(dbusSpy, QStringLiteral("Alias"), value);
0171 
0172         QCOMPARE(unit.device->name(), value);
0173         QCOMPARE(unit.dbusDevice->alias(), value);
0174     }
0175 }
0176 
0177 void DeviceTest::setTrustedTest()
0178 {
0179     for (const DeviceUnit &unit : m_units) {
0180         QSignalSpy deviceSpy(unit.device.data(), SIGNAL(trustedChanged(bool)));
0181         QSignalSpy dbusSpy(unit.dbusProperties, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList)));
0182 
0183         bool value = !unit.device->isTrusted();
0184 
0185         unit.device->setTrusted(value);
0186         QTRY_COMPARE(deviceSpy.count(), 1);
0187 
0188         QList<QVariant> arguments = deviceSpy.takeFirst();
0189         QCOMPARE(arguments.at(0).toBool(), value);
0190         Autotests::verifyPropertiesChangedSignal(dbusSpy, QStringLiteral("Trusted"), value);
0191 
0192         QCOMPARE(unit.device->isTrusted(), value);
0193         QCOMPARE(unit.dbusDevice->trusted(), value);
0194     }
0195 }
0196 
0197 void DeviceTest::setBlockedTest()
0198 {
0199     for (const DeviceUnit &unit : m_units) {
0200         QSignalSpy deviceSpy(unit.device.data(), SIGNAL(blockedChanged(bool)));
0201         QSignalSpy dbusSpy(unit.dbusProperties, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList)));
0202 
0203         bool value = !unit.device->isBlocked();
0204 
0205         unit.device->setBlocked(value);
0206         QTRY_COMPARE(deviceSpy.count(), 1);
0207 
0208         QList<QVariant> arguments = deviceSpy.takeFirst();
0209         QCOMPARE(arguments.at(0).toBool(), value);
0210         Autotests::verifyPropertiesChangedSignal(dbusSpy, QStringLiteral("Blocked"), value);
0211 
0212         QCOMPARE(unit.device->isBlocked(), value);
0213         QCOMPARE(unit.dbusDevice->blocked(), value);
0214     }
0215 }
0216 
0217 void DeviceTest::deviceRemovedTest()
0218 {
0219     for (const DeviceUnit &unit : m_units) {
0220         QSignalSpy managerSpy(m_manager, SIGNAL(deviceRemoved(DevicePtr)));
0221         QSignalSpy adapterSpy(unit.device->adapter().data(), SIGNAL(deviceRemoved(DevicePtr)));
0222         QSignalSpy deviceSpy(unit.device.data(), SIGNAL(deviceRemoved(DevicePtr)));
0223 
0224         QVariantMap properties;
0225         properties[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath(unit.device->ubi()));
0226         FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("remove-device"), properties);
0227 
0228         QTRY_COMPARE(managerSpy.count(), 1);
0229         QTRY_COMPARE(adapterSpy.count(), 1);
0230         QTRY_COMPARE(deviceSpy.count(), 1);
0231 
0232         QCOMPARE(managerSpy.at(0).at(0).value<DevicePtr>(), unit.device);
0233         QCOMPARE(adapterSpy.at(0).at(0).value<DevicePtr>(), unit.device);
0234         QCOMPARE(deviceSpy.at(0).at(0).value<DevicePtr>(), unit.device);
0235     }
0236 }
0237 
0238 QString DeviceTest::deviceIcon(org::bluez::Device1 *device) const
0239 {
0240     quint32 classNum = device->deviceClass();
0241     switch ((classNum & 0x1f00) >> 8) {
0242     case 0x04:
0243         switch ((classNum & 0xfc) >> 2) {
0244         case 0x01:
0245         case 0x02:
0246             return QStringLiteral("audio-headset");
0247         case 0x06:
0248             return QStringLiteral("audio-headphones");
0249         }
0250     }
0251     return device->icon();
0252 }
0253 
0254 qint16 DeviceTest::deviceRssi(org::bluez::Device1 *device) const
0255 {
0256     qint16 rssi = device->rSSI();
0257     if (!rssi) {
0258         rssi = -32768;
0259     }
0260     return rssi;
0261 }
0262 
0263 QTEST_MAIN(DeviceTest)
0264 
0265 #include "moc_devicetest.cpp"