add display pin mock device
This commit is contained in:
parent
ec25870bfd
commit
10497313ea
@ -56,6 +56,11 @@ DeviceManager::DeviceError DevicePluginMock::discoverDevices(const DeviceClassId
|
||||
m_discoveredDeviceCount = params.paramValue("resultCount").toInt();
|
||||
QTimer::singleShot(1000, this, SLOT(emitPushButtonDevicesDiscovered()));
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
} else if (deviceClassId == mockDisplayPinDeviceClassId) {
|
||||
qCDebug(dcMockDevice) << "starting mock display pin discovery:" << params;
|
||||
m_discoveredDeviceCount = params.paramValue("resultCount").toInt();
|
||||
QTimer::singleShot(1000, this, SLOT(emitDisplayPinDevicesDiscovered()));
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
}
|
||||
return DeviceManager::DeviceErrorDeviceClassNotFound;
|
||||
}
|
||||
@ -94,7 +99,11 @@ DeviceManager::DeviceSetupStatus DevicePluginMock::setupDevice(Device *device)
|
||||
} else if (device->deviceClassId() == mockPushButtonDeviceClassId) {
|
||||
qCDebug(dcMockDevice) << "Setup PushButton Mock device" << device->params();
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
} else if (device->deviceClassId() == mockDisplayPinDeviceClassId) {
|
||||
qCDebug(dcMockDevice) << "Setup DisplayPin Mock device" << device->params();
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
|
||||
@ -133,18 +142,37 @@ DeviceManager::DeviceSetupStatus DevicePluginMock::confirmPairing(const PairingT
|
||||
|
||||
qCDebug(dcMockDevice) << "Confirm pairing";
|
||||
|
||||
if (deviceClassId != mockPushButtonDeviceClassId) {
|
||||
qCWarning(dcMockDevice) << "Invalid deviceclassId -> no pairing possible with this device";
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
if (!m_pushbuttonPressed) {
|
||||
qCDebug(dcMockDevice) << "PushButton not pressed yet!";
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
if (deviceClassId == mockPushButtonDeviceClassId) {
|
||||
if (!m_pushbuttonPressed) {
|
||||
qCDebug(dcMockDevice) << "PushButton not pressed yet!";
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
|
||||
m_pairingId = pairingTransactionId;
|
||||
QTimer::singleShot(1000, this, SLOT(onPushButtonPairingFinished()));
|
||||
return DeviceManager::DeviceSetupStatusAsync;
|
||||
} else if (deviceClassId == mockDisplayPinDeviceClassId) {
|
||||
if (secret != "243681") {
|
||||
qCWarning(dcMockDevice) << "Invalid pin:" << secret;
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
m_pairingId = pairingTransactionId;
|
||||
QTimer::singleShot(500, this, SLOT(onDisplayPinPairingFinished()));
|
||||
return DeviceManager::DeviceSetupStatusAsync;
|
||||
}
|
||||
|
||||
m_pairingId = pairingTransactionId;
|
||||
QTimer::singleShot(1000, this, SLOT(onPushButtonPairingFinished()));
|
||||
return DeviceManager::DeviceSetupStatusAsync;
|
||||
qCWarning(dcMockDevice) << "Invalid deviceclassId -> no pairing possible with this device";
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError DevicePluginMock::displayPin(const PairingTransactionId &pairingTransactionId, const DeviceDescriptor &deviceDescriptor)
|
||||
{
|
||||
Q_UNUSED(pairingTransactionId)
|
||||
Q_UNUSED(deviceDescriptor)
|
||||
|
||||
qCDebug(dcMockDevice) << "Display pin!! The pin is 243681";
|
||||
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
QList<ParamType> DevicePluginMock::configurationDescription() const
|
||||
@ -177,7 +205,7 @@ DeviceManager::DeviceError DevicePluginMock::executeAction(Device *device, const
|
||||
|
||||
m_daemons.value(device)->actionExecuted(action.actionTypeId());
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
} else if (device->deviceClassId() == mockPushButtonDeviceClassId) {
|
||||
} else if (device->deviceClassId() == mockPushButtonDeviceClassId || device->deviceClassId() == mockDisplayPinDeviceClassId) {
|
||||
if (action.actionTypeId() == colorActionTypeId) {
|
||||
QString colorString = action.param("color").value().toString();
|
||||
QColor color(colorString);
|
||||
@ -259,7 +287,7 @@ void DevicePluginMock::emitPushButtonDevicesDiscovered()
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
|
||||
if (m_discoveredDeviceCount > 0) {
|
||||
DeviceDescriptor d1(mockDeviceClassId, "Mock Device (Push Button)", "1");
|
||||
DeviceDescriptor d1(mockPushButtonDeviceClassId, "Mock Device (Push Button)", "1");
|
||||
ParamList params;
|
||||
Param name("name", "PushButton Mock Device 1");
|
||||
params.append(name);
|
||||
@ -268,7 +296,7 @@ void DevicePluginMock::emitPushButtonDevicesDiscovered()
|
||||
}
|
||||
|
||||
if (m_discoveredDeviceCount > 1) {
|
||||
DeviceDescriptor d2(mockDeviceClassId, "Mock Device (Push Button)", "2");
|
||||
DeviceDescriptor d2(mockPushButtonDeviceClassId, "Mock Device (Push Button)", "2");
|
||||
ParamList params;
|
||||
Param name("name", "PushButton Mock Device 2");
|
||||
params.append(name);
|
||||
@ -280,7 +308,31 @@ void DevicePluginMock::emitPushButtonDevicesDiscovered()
|
||||
m_pushbuttonPressed = false;
|
||||
QTimer::singleShot(3000, this, SLOT(onPushButtonPressed()));
|
||||
qDebug() << "Start PushButton timer (will be pressed in 3 second)";
|
||||
}
|
||||
|
||||
void DevicePluginMock::emitDisplayPinDevicesDiscovered()
|
||||
{
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
|
||||
if (m_discoveredDeviceCount > 0) {
|
||||
DeviceDescriptor d1(mockDisplayPinDeviceClassId, "Mock Device (Display Pin)", "1");
|
||||
ParamList params;
|
||||
Param name("name", "DisplayPin Mock Device 1");
|
||||
params.append(name);
|
||||
d1.setParams(params);
|
||||
deviceDescriptors.append(d1);
|
||||
}
|
||||
|
||||
if (m_discoveredDeviceCount > 1) {
|
||||
DeviceDescriptor d2(mockDisplayPinDeviceClassId, "Mock Device (Display Pin)", "2");
|
||||
ParamList params;
|
||||
Param name("name", "DisplayPin Mock Device 2");
|
||||
params.append(name);
|
||||
d2.setParams(params);
|
||||
deviceDescriptors.append(d2);
|
||||
}
|
||||
|
||||
emit devicesDiscovered(mockDisplayPinDeviceClassId, deviceDescriptors);
|
||||
}
|
||||
|
||||
void DevicePluginMock::onPushButtonPressed()
|
||||
@ -316,3 +368,9 @@ void DevicePluginMock::onPushButtonPairingFinished()
|
||||
qCDebug(dcMockDevice) << "Pairing PushButton Device finished";
|
||||
emit pairingFinished(m_pairingId, DeviceManager::DeviceSetupStatusSuccess);
|
||||
}
|
||||
|
||||
void DevicePluginMock::onDisplayPinPairingFinished()
|
||||
{
|
||||
qCDebug(dcMockDevice) << "Pairing DisplayPin Device finished";
|
||||
emit pairingFinished(m_pairingId, DeviceManager::DeviceSetupStatusSuccess);
|
||||
}
|
||||
|
||||
@ -48,6 +48,7 @@ public:
|
||||
void startMonitoringAutoDevices() override;
|
||||
|
||||
DeviceManager::DeviceSetupStatus confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList ¶ms, const QString &secret) override;
|
||||
DeviceManager::DeviceError displayPin(const PairingTransactionId &pairingTransactionId, const DeviceDescriptor &deviceDescriptor) override;
|
||||
|
||||
QList<ParamType> configurationDescription() const override;
|
||||
|
||||
@ -59,11 +60,13 @@ private slots:
|
||||
void triggerEvent(const EventTypeId &id);
|
||||
void emitDevicesDiscovered();
|
||||
void emitPushButtonDevicesDiscovered();
|
||||
void emitDisplayPinDevicesDiscovered();
|
||||
void emitDeviceSetupFinished();
|
||||
void emitActionExecuted();
|
||||
|
||||
void onPushButtonPressed();
|
||||
void onPushButtonPairingFinished();
|
||||
void onDisplayPinPairingFinished();
|
||||
|
||||
private:
|
||||
QHash<Device*, HttpDaemon*> m_daemons;
|
||||
|
||||
@ -269,6 +269,80 @@
|
||||
"name": "Timout action"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceClassId": "296f1fd4-e893-46b2-8a42-50d1bceb8730",
|
||||
"idName": "mockDisplayPin",
|
||||
"name": "Mock Device (Display Pin)",
|
||||
"createMethods": ["discovery"],
|
||||
"setupMethod": "displayPin",
|
||||
"pairingInfo": "Please enter the secret which normaly will be displayed on the device. For the mockdevice the pin is 243681.",
|
||||
"discoveryParamTypes": [
|
||||
{
|
||||
"name": "resultCount",
|
||||
"type": "int",
|
||||
"defaultValue": 2,
|
||||
"allowedValues": [1, 2]
|
||||
}
|
||||
],
|
||||
"paramTypes": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine",
|
||||
"defaultValue": "Mock device",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "pin",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine",
|
||||
"defaultValue": "243681",
|
||||
"readOnly": true
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "20dc7c22-c50e-42db-837c-2bbced939f8e",
|
||||
"idName": "color",
|
||||
"name": "color",
|
||||
"type": "QColor",
|
||||
"defaultValue": "#000000",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "72981c04-267a-4ba0-a59e-9921d2f3af9c",
|
||||
"idName": "percentage",
|
||||
"name": "percentage",
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0,
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "05f63f9c-f61e-4dcf-ad55-3f13fde2765b",
|
||||
"idName": "allowedValues",
|
||||
"name": "allowed values",
|
||||
"type": "QString",
|
||||
"defaultValue": "String value 1",
|
||||
"possibleValues": [
|
||||
"String value 1",
|
||||
"String value 2",
|
||||
"String value 3",
|
||||
"String value 4"
|
||||
],
|
||||
"writable": true
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "54646e7c-bc54-4895-81a2-590d72d120f9",
|
||||
"idName": "timeout",
|
||||
"name": "Timout action"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -64,6 +64,9 @@ private slots:
|
||||
void addPushButtonDevices_data();
|
||||
void addPushButtonDevices();
|
||||
|
||||
void addDisplayPinDevices_data();
|
||||
void addDisplayPinDevices();
|
||||
|
||||
void getActionTypes_data();
|
||||
void getActionTypes();
|
||||
|
||||
@ -466,6 +469,69 @@ void TestDevices::addPushButtonDevices()
|
||||
}
|
||||
}
|
||||
|
||||
void TestDevices::addDisplayPinDevices_data()
|
||||
{
|
||||
QTest::addColumn<DeviceClassId>("deviceClassId");
|
||||
QTest::addColumn<DeviceManager::DeviceError>("error");
|
||||
QTest::addColumn<QString>("secret");
|
||||
|
||||
QTest::newRow("Valid: Add DisplayPin device") << mockDisplayPinDeviceClassId << DeviceManager::DeviceErrorNoError << "243681";
|
||||
QTest::newRow("Invalid: Add DisplayPin device (wrong pin)") << mockDisplayPinDeviceClassId << DeviceManager::DeviceErrorSetupFailed << "243682";
|
||||
}
|
||||
|
||||
void TestDevices::addDisplayPinDevices()
|
||||
{
|
||||
QFETCH(DeviceClassId, deviceClassId);
|
||||
QFETCH(DeviceManager::DeviceError, error);
|
||||
QFETCH(QString, secret);
|
||||
|
||||
// Discover device
|
||||
QVariantList discoveryParams;
|
||||
QVariantMap resultCountParam;
|
||||
resultCountParam.insert("name", "resultCount");
|
||||
resultCountParam.insert("value", 1);
|
||||
discoveryParams.append(resultCountParam);
|
||||
|
||||
QVariantMap params;
|
||||
params.insert("deviceClassId", deviceClassId);
|
||||
params.insert("discoveryParams", discoveryParams);
|
||||
QVariant response = injectAndWait("Devices.GetDiscoveredDevices", params);
|
||||
|
||||
verifyDeviceError(response, DeviceManager::DeviceErrorNoError);
|
||||
QCOMPARE(response.toMap().value("params").toMap().value("deviceDescriptors").toList().count(), 1);
|
||||
|
||||
// Pair device
|
||||
DeviceDescriptorId descriptorId = DeviceDescriptorId(response.toMap().value("params").toMap().value("deviceDescriptors").toList().first().toMap().value("id").toString());
|
||||
params.clear();
|
||||
params.insert("deviceClassId", deviceClassId);
|
||||
params.insert("deviceDescriptorId", descriptorId.toString());
|
||||
response = injectAndWait("Devices.PairDevice", params);
|
||||
|
||||
verifyDeviceError(response);
|
||||
|
||||
PairingTransactionId pairingTransactionId(response.toMap().value("params").toMap().value("pairingTransactionId").toString());
|
||||
QString displayMessage = response.toMap().value("params").toMap().value("displayMessage").toString();
|
||||
|
||||
//qDebug() << "displayMessage" << displayMessage;
|
||||
|
||||
params.clear();
|
||||
params.insert("pairingTransactionId", pairingTransactionId.toString());
|
||||
params.insert("secret", secret);
|
||||
response = injectAndWait("Devices.ConfirmPairing", params);
|
||||
|
||||
verifyDeviceError(response, error);
|
||||
|
||||
if (error == DeviceManager::DeviceErrorNoError) {
|
||||
DeviceId deviceId(response.toMap().value("params").toMap().value("deviceId").toString());
|
||||
params.clear();
|
||||
params.insert("deviceId", deviceId.toString());
|
||||
response = injectAndWait("Devices.RemoveConfiguredDevice", params);
|
||||
verifyDeviceError(response);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void TestDevices::getActionTypes_data()
|
||||
{
|
||||
QTest::addColumn<DeviceClassId>("deviceClassId");
|
||||
|
||||
@ -42,6 +42,7 @@ VendorId guhVendorId = VendorId("2062d64d-3232-433c-88bc-0d33c0ba2ba6");
|
||||
DeviceClassId mockDeviceClassId = DeviceClassId("753f0d32-0468-4d08-82ed-1964aab03298");
|
||||
DeviceClassId mockDeviceAutoClassId = DeviceClassId("ab4257b3-7548-47ee-9bd4-7dc3004fd197");
|
||||
DeviceClassId mockPushButtonDeviceClassId = DeviceClassId("9e03144c-e436-4eea-82d9-ccb33ef778db");
|
||||
DeviceClassId mockDisplayPinDeviceClassId = DeviceClassId("296f1fd4-e893-46b2-8a42-50d1bceb8730");
|
||||
DeviceClassId mockDeviceDiscoveryClassId = DeviceClassId("1bbaf751-36b7-4d3d-b05a-58dab2a3be8c");
|
||||
DeviceClassId mockDeviceAsyncSetupClassId = DeviceClassId("c08a8b27-8200-413d-b96b-4cff78b864d9");
|
||||
DeviceClassId mockDeviceBrokenClassId = DeviceClassId("ba5fb404-c9ce-4db4-8cd4-f48c61c24b13");
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
extern DeviceClassId mockDeviceClassId;
|
||||
extern DeviceClassId mockDeviceAutoClassId;
|
||||
extern DeviceClassId mockPushButtonDeviceClassId;
|
||||
extern DeviceClassId mockDisplayPinDeviceClassId;
|
||||
extern DeviceClassId mockDeviceDiscoveryClassId;
|
||||
extern DeviceClassId mockDeviceAsyncSetupClassId;
|
||||
extern DeviceClassId mockDeviceBrokenClassId;
|
||||
|
||||
@ -50,6 +50,9 @@ private slots:
|
||||
void addPushButtonDevices_data();
|
||||
void addPushButtonDevices();
|
||||
|
||||
void addDisplayPinDevices_data();
|
||||
void addDisplayPinDevices();
|
||||
|
||||
void executeAction_data();
|
||||
void executeAction();
|
||||
|
||||
@ -335,6 +338,118 @@ void TestRestDevices::addPushButtonDevices()
|
||||
nam->deleteLater();
|
||||
}
|
||||
|
||||
void TestRestDevices::addDisplayPinDevices_data()
|
||||
{
|
||||
QTest::addColumn<DeviceClassId>("deviceClassId");
|
||||
QTest::addColumn<int>("expectedStatusCode");
|
||||
QTest::addColumn<QString>("secret");
|
||||
|
||||
QTest::newRow("Valid: Add DisplayPin device") << mockDisplayPinDeviceClassId << 200 << "243681";
|
||||
QTest::newRow("Invalid: Add DisplayPin device (wrong pin)") << mockDisplayPinDeviceClassId << 500 << "243682";
|
||||
}
|
||||
|
||||
void TestRestDevices::addDisplayPinDevices()
|
||||
{
|
||||
QFETCH(DeviceClassId, deviceClassId);
|
||||
QFETCH(int, expectedStatusCode);
|
||||
QFETCH(QString, secret);
|
||||
|
||||
// Discover device
|
||||
QVariantList discoveryParams;
|
||||
QVariantMap resultCountParam;
|
||||
resultCountParam.insert("name", "resultCount");
|
||||
resultCountParam.insert("value", 1);
|
||||
discoveryParams.append(resultCountParam);
|
||||
|
||||
// Discover
|
||||
QVariantMap params;
|
||||
params.insert("deviceClassId", deviceClassId);
|
||||
params.insert("discoveryParams", discoveryParams);
|
||||
|
||||
QNetworkAccessManager *nam = new QNetworkAccessManager(this);
|
||||
QSignalSpy clientSpy(nam, SIGNAL(finished(QNetworkReply*)));
|
||||
|
||||
QUrl url(QString("http://localhost:3333/api/v1/deviceclasses/%1/discover").arg(deviceClassId.toString()));
|
||||
|
||||
QUrlQuery query;
|
||||
query.addQueryItem("params", QJsonDocument::fromVariant(discoveryParams).toJson(QJsonDocument::Compact));
|
||||
url.setQuery(query);
|
||||
|
||||
clientSpy.clear();
|
||||
QNetworkRequest request(url);
|
||||
QNetworkReply *reply = nam->get(request);
|
||||
clientSpy.wait();
|
||||
QCOMPARE(clientSpy.count(), 1);
|
||||
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
QCOMPARE(statusCode, 200);
|
||||
QByteArray data = reply->readAll();
|
||||
reply->deleteLater();
|
||||
|
||||
// check response
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
QCOMPARE(error.error, QJsonParseError::NoError);
|
||||
QVariantList foundDevices = jsonDoc.toVariant().toList();
|
||||
QCOMPARE(foundDevices.count(), 1);
|
||||
|
||||
DeviceDescriptorId deviceDescriptoId(foundDevices.first().toMap().value("id").toString());
|
||||
|
||||
// Pair
|
||||
params.clear();
|
||||
params.insert("deviceClassId", deviceClassId.toString());
|
||||
params.insert("deviceDescriptorId", deviceDescriptoId);
|
||||
|
||||
QNetworkRequest pairRequest(QUrl("http://localhost:3333/api/v1/devices/pair"));
|
||||
clientSpy.clear();
|
||||
reply = nam->post(pairRequest, QJsonDocument::fromVariant(params).toJson(QJsonDocument::Compact));
|
||||
clientSpy.wait();
|
||||
QCOMPARE(clientSpy.count(), 1);
|
||||
statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
QCOMPARE(statusCode, 200);
|
||||
data = reply->readAll();
|
||||
reply->deleteLater();
|
||||
|
||||
// check response
|
||||
jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
QCOMPARE(error.error, QJsonParseError::NoError);
|
||||
PairingTransactionId pairingTransactionId(jsonDoc.toVariant().toMap().value("pairingTransactionId").toString());
|
||||
QString displayMessage = jsonDoc.toVariant().toMap().value("displayMessage").toString();
|
||||
|
||||
qDebug() << "displayMessage" << displayMessage;
|
||||
|
||||
// Confirm pairing
|
||||
params.clear();
|
||||
params.insert("pairingTransactionId", pairingTransactionId.toString());
|
||||
params.insert("secret", secret);
|
||||
|
||||
QNetworkRequest confirmPairingRequest(QUrl("http://localhost:3333/api/v1/devices/confirmpairing"));
|
||||
clientSpy.clear();
|
||||
reply = nam->post(confirmPairingRequest, QJsonDocument::fromVariant(params).toJson(QJsonDocument::Compact));
|
||||
clientSpy.wait();
|
||||
QCOMPARE(clientSpy.count(), 1);
|
||||
statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
QCOMPARE(statusCode, expectedStatusCode);
|
||||
data = reply->readAll();
|
||||
reply->deleteLater();
|
||||
|
||||
if (expectedStatusCode == 200) {
|
||||
jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
QCOMPARE(error.error, QJsonParseError::NoError);
|
||||
|
||||
DeviceId deviceId(jsonDoc.toVariant().toMap().value("id").toString());
|
||||
// delete it
|
||||
request.setUrl(QUrl(QString("http://localhost:3333/api/v1/devices/%1").arg(deviceId.toString())));
|
||||
clientSpy.clear();
|
||||
reply = nam->deleteResource(request);
|
||||
clientSpy.wait();
|
||||
QCOMPARE(clientSpy.count(), 1);
|
||||
statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
reply->deleteLater();
|
||||
QCOMPARE(statusCode, 200);
|
||||
}
|
||||
nam->deleteLater();
|
||||
}
|
||||
|
||||
void TestRestDevices::executeAction_data()
|
||||
{
|
||||
QTest::addColumn<DeviceId>("deviceId");
|
||||
|
||||
Reference in New Issue
Block a user