1/*
2 * SPDX-FileCopyrightText: 2021 Ivan Podkurkov <podkiva2@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 "gattserviceremotetest.h"
8#include "adapter.h"
9#include "autotests.h"
10#include "device.h"
11#include "initmanagerjob.h"
12#include "pendingcall.h"
13
14#include <QSignalSpy>
15#include <QTest>
16
17namespace BluezQt
18{
19extern void bluezqt_initFakeBluezTestRun();
20}
21
22using namespace BluezQt;
23
24GattServiceRemoteTest::GattServiceRemoteTest()
25 : m_manager(nullptr)
26{
27 Autotests::registerMetatypes();
28}
29
30void GattServiceRemoteTest::initTestCase()
31{
32 QDBusConnection connection = QDBusConnection::sessionBus();
33 QString service = QStringLiteral("org.kde.bluezqt.fakebluez");
34
35 bluezqt_initFakeBluezTestRun();
36
37 FakeBluez::start();
38 FakeBluez::runTest(QStringLiteral("bluez-standard"));
39
40 // Create adapters
41 QDBusObjectPath adapter1 = QDBusObjectPath(QStringLiteral("/org/bluez/hci0"));
42 QVariantMap adapterProps;
43 adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter1);
44 adapterProps[QStringLiteral("Address")] = QStringLiteral("1C:E5:C3:BC:94:7E");
45 adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter");
46 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps);
47
48 QDBusObjectPath adapter2 = QDBusObjectPath(QStringLiteral("/org/bluez/hci1"));
49 adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter2);
50 adapterProps[QStringLiteral("Address")] = QStringLiteral("2E:3A:C3:BC:85:7C");
51 adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter2");
52 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps);
53
54 // Create devices
55 QVariantMap deviceProps;
56 deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75"));
57 deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0"));
58 deviceProps[QStringLiteral("Address")] = QStringLiteral("40:79:6A:0C:39:75");
59 deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice");
60 deviceProps[QStringLiteral("Alias")] = QStringLiteral("TestAlias");
61 deviceProps[QStringLiteral("Icon")] = QStringLiteral("phone");
62 deviceProps[QStringLiteral("Class")] = QVariant::fromValue(quint32(101));
63 deviceProps[QStringLiteral("Appearance")] = QVariant::fromValue(quint16(25));
64 deviceProps[QStringLiteral("UUIDs")] = QStringList();
65 deviceProps[QStringLiteral("Paired")] = false;
66 deviceProps[QStringLiteral("Connected")] = false;
67 deviceProps[QStringLiteral("Trusted")] = false;
68 deviceProps[QStringLiteral("Blocked")] = false;
69 deviceProps[QStringLiteral("LegacyPairing")] = false;
70 deviceProps[QStringLiteral("RSSI")] = QVariant::fromValue(qint16(20));
71 deviceProps[QStringLiteral("Modalias")] = QStringLiteral("bluetooth:v001Dp1200d1236");
72 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps);
73
74 deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75"));
75 deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1"));
76 deviceProps[QStringLiteral("Address")] = QStringLiteral("50:79:6A:0C:39:75");
77 deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice2");
78 deviceProps[QStringLiteral("Alias")] = QStringLiteral("TestAlias2");
79 deviceProps[QStringLiteral("Icon")] = QStringLiteral("joypad");
80 deviceProps[QStringLiteral("Class")] = QVariant::fromValue(quint32(201));
81 deviceProps[QStringLiteral("Appearance")] = QVariant::fromValue(quint16(32));
82 deviceProps[QStringLiteral("UUIDs")] = QStringList();
83 deviceProps[QStringLiteral("Paired")] = true;
84 deviceProps[QStringLiteral("Connected")] = false;
85 deviceProps[QStringLiteral("Trusted")] = true;
86 deviceProps[QStringLiteral("Blocked")] = false;
87 deviceProps[QStringLiteral("LegacyPairing")] = false;
88 deviceProps[QStringLiteral("RSSI")] = QVariant::fromValue(qint16(-15));
89 deviceProps[QStringLiteral("Modalias")] = QStringLiteral("bluetooth:v001Dp1100d1236");
90 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps);
91
92 // Create services
93 QVariantMap serviceProps;
94 serviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75/service0"));
95 serviceProps[QStringLiteral("UUID")] = QStringLiteral("04FA28C0-2D0C-11EC-8D3D-0242AC130003");
96 serviceProps[QStringLiteral("Primary")] = true;
97 serviceProps[QStringLiteral("Device")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75"));
98 serviceProps[QStringLiteral("Includes")] = QVariant::fromValue(QList<QDBusObjectPath>());
99 serviceProps[QStringLiteral("Handle")] = QVariant::fromValue(qint16(1));
100 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-gatt-service"), serviceProps);
101
102 serviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75/service0"));
103 serviceProps[QStringLiteral("UUID")] = QStringLiteral("0663A394-9A76-4361-9DE6-82577B82AC9A");
104 serviceProps[QStringLiteral("Primary")] = true;
105 serviceProps[QStringLiteral("Device")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75"));
106 serviceProps[QStringLiteral("Includes")] = QVariant::fromValue(QList<QDBusObjectPath>());
107 serviceProps[QStringLiteral("Handle")] = QVariant::fromValue(qint16(2));
108 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-gatt-service"), serviceProps);
109
110 m_manager = new Manager();
111 InitManagerJob *initJob = m_manager->init();
112 initJob->exec();
113 QVERIFY(!initJob->error());
114
115 for (const AdapterPtr &adapter : m_manager->adapters()) {
116 QVERIFY(!adapter->ubi().isEmpty());
117
118 for (const DevicePtr &device : adapter->devices()) {
119 QVERIFY(!device->ubi().isEmpty());
120
121 for (const GattServiceRemotePtr &gattService : device->gattServices()) {
122 QVERIFY(!gattService->ubi().isEmpty());
123
124 GattServiceRemoteUnit u;
125 u.service = gattService;
126 u.dbusService = new org::bluez::GattService1(service, gattService->ubi(), connection, this);
127 u.dbusProperties = new org::freedesktop::DBus::Properties(service, gattService->ubi(), connection, this);
128 m_units.append(u);
129 }
130
131 QCOMPARE(device->gattServices().count(), 1);
132 }
133 }
134
135 QCOMPARE(m_manager->adapters().count(), 2);
136 QCOMPARE(m_manager->devices().count(), 2);
137}
138
139void GattServiceRemoteTest::cleanupTestCase()
140{
141 for (const GattServiceRemoteUnit &unit : std::as_const(m_units)) {
142 delete unit.dbusService;
143 delete unit.dbusProperties;
144 }
145
146 delete m_manager;
147
148 FakeBluez::stop();
149}
150
151void GattServiceRemoteTest::getPropertiesTest()
152{
153 for (const GattServiceRemoteUnit &unit : std::as_const(m_units)) {
154 QCOMPARE(unit.service->ubi(), unit.dbusService->path());
155 QCOMPARE(unit.service->uuid(), unit.dbusService->uUID());
156 QCOMPARE(unit.service->isPrimary(), unit.dbusService->primary());
157 QCOMPARE(unit.service->device()->ubi(), unit.dbusService->device().path());
158 QCOMPARE(unit.service->includes(), unit.dbusService->includes());
159 QCOMPARE(unit.service->handle(), unit.dbusService->handle());
160 }
161}
162
163void GattServiceRemoteTest::setHandleTest()
164{
165 for (const GattServiceRemoteUnit &unit : std::as_const(m_units)) {
166 QSignalSpy serviceSpy(unit.service.data(), SIGNAL(handleChanged(quint16)));
167 QSignalSpy dbusSpy(unit.dbusProperties, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList)));
168
169 quint16 value = unit.service->handle() + 3;
170
171 unit.service->setHandle(value);
172 QTRY_COMPARE(serviceSpy.count(), 1);
173
174 QList<QVariant> arguments = serviceSpy.takeFirst();
175 QCOMPARE(arguments.at(0).toUInt(), value);
176 Autotests::verifyPropertiesChangedSignal(dbusSpy, QStringLiteral("Handle"), value);
177
178 QCOMPARE(unit.service->handle(), value);
179 QCOMPARE(unit.dbusService->handle(), value);
180 }
181}
182
183void GattServiceRemoteTest::serviceRemovedTest()
184{
185 for (const GattServiceRemoteUnit &unit : std::as_const(m_units)) {
186 QSignalSpy deviceSpy(unit.service->device().data(), SIGNAL(gattServiceRemoved(GattServiceRemotePtr)));
187
188 QVariantMap properties;
189 properties[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath(unit.service->ubi()));
190 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("remove-gatt-service"), properties);
191
192 QTRY_COMPARE(deviceSpy.count(), 1);
193
194 QCOMPARE(deviceSpy.at(0).at(0).value<GattServiceRemotePtr>(), unit.service);
195 }
196}
197
198QTEST_MAIN(GattServiceRemoteTest)
199
200#include "moc_gattserviceremotetest.cpp"
201

source code of bluez-qt/autotests/gattserviceremotetest.cpp