Add deprecation warnings
This commit is contained in:
parent
5be6e6e19d
commit
fa1cd3605c
@ -385,7 +385,7 @@ DeviceHandler::DeviceHandler(QObject *parent) :
|
||||
params.clear(); returns.clear();
|
||||
description = "Emitted whenever an Event is triggered.";
|
||||
params.insert("event", objectRef<Event>());
|
||||
registerNotification("EventTriggered", description, params, "Please use Devices.EventTriggered instead.");
|
||||
registerNotification("EventTriggered", description, params);
|
||||
connect(NymeaCore::instance(), &NymeaCore::eventTriggered, this, [this](const Event &event){
|
||||
QVariantMap params;
|
||||
params.insert("event", pack(event));
|
||||
|
||||
@ -467,13 +467,17 @@ bool JsonRPCServerImplementation::registerExperienceHandler(JsonHandler *handler
|
||||
/*! Send a JSON success response to the client with the given \a clientId,
|
||||
* \a commandId and \a params to the inerted \l{TransportInterface}.
|
||||
*/
|
||||
void JsonRPCServerImplementation::sendResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QVariantMap ¶ms)
|
||||
void JsonRPCServerImplementation::sendResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QVariantMap ¶ms, const QString &deprecationWarning)
|
||||
{
|
||||
QVariantMap response;
|
||||
response.insert("id", commandId);
|
||||
response.insert("status", "success");
|
||||
response.insert("params", params);
|
||||
|
||||
if (!deprecationWarning.isEmpty()) {
|
||||
response.insert("deprecationWarning", deprecationWarning);
|
||||
}
|
||||
|
||||
QByteArray data = QJsonDocument::fromVariant(response).toJson(QJsonDocument::Compact);
|
||||
qCDebug(dcJsonRpcTraffic()) << "Sending data:" << data;
|
||||
interface->sendData(clientId, data);
|
||||
@ -694,7 +698,15 @@ void JsonRPCServerImplementation::processJsonPacket(TransportInterface *interfac
|
||||
Q_ASSERT_X((targetNamespace == "JSONRPC" && method == "Introspect") || validator.validateReturns(reply->data(), targetNamespace + '.' + method, m_api).success(),
|
||||
validator.result().where().toUtf8(),
|
||||
validator.result().errorString().toUtf8() + "\nReturn value:\n" + QJsonDocument::fromVariant(reply->data()).toJson());
|
||||
sendResponse(interface, clientId, commandId, reply->data());
|
||||
|
||||
QString deprecationWarning;
|
||||
if (m_api.value("methods").toMap().value(targetNamespace + '.' + method).toMap().contains("deprecated")) {
|
||||
deprecationWarning = m_api.value("methods").toMap().value(targetNamespace + '.' + method).toMap().value("deprecated").toString();
|
||||
qCWarning(dcJsonRpc()) << "Client uses deprecated API. Please update client implementation!";
|
||||
qCWarning(dcJsonRpc()) << targetNamespace + '.' + method + ':' << deprecationWarning;
|
||||
}
|
||||
|
||||
sendResponse(interface, clientId, commandId, reply->data(), deprecationWarning);
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
@ -704,6 +716,16 @@ void JsonRPCServerImplementation::sendNotification(const QVariantMap ¶ms)
|
||||
JsonHandler *handler = qobject_cast<JsonHandler *>(sender());
|
||||
QMetaMethod method = handler->metaObject()->method(senderSignalIndex());
|
||||
|
||||
QList<QUuid> clientsToBeNotified;
|
||||
foreach (const QUuid &clientId, m_clientNotifications.keys()) {
|
||||
if (m_clientNotifications.value(clientId).contains(handler->name())) {
|
||||
clientsToBeNotified.append(clientId);
|
||||
}
|
||||
}
|
||||
if (clientsToBeNotified.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap notification;
|
||||
notification.insert("id", m_notificationId++);
|
||||
notification.insert("notification", handler->name() + "." + method.name());
|
||||
@ -713,14 +735,20 @@ void JsonRPCServerImplementation::sendNotification(const QVariantMap ¶ms)
|
||||
Q_ASSERT_X(validator.validateNotificationParams(params, handler->name() + '.' + method.name(), m_api).success(),
|
||||
validator.result().where().toUtf8(),
|
||||
validator.result().errorString().toUtf8());
|
||||
|
||||
if (m_api.value("notifications").toMap().value(handler->name() + '.' + method.name()).toMap().contains("deprecated")) {
|
||||
QString deprecationMessage = m_api.value("notifications").toMap().value(handler->name() + '.' + method.name()).toMap().value("deprecated").toString();
|
||||
qCWarning(dcJsonRpc()) << "Client uses deprecated API. Please update client implementation!";
|
||||
qCWarning(dcJsonRpc()) << handler->name() + '.' + method.name() + ':' << deprecationMessage;
|
||||
notification.insert("deprecationWarning", deprecationMessage);
|
||||
}
|
||||
|
||||
QByteArray data = QJsonDocument::fromVariant(notification).toJson(QJsonDocument::Compact);
|
||||
qCDebug(dcJsonRpc()) << "Sending notification:" << handler->name() + "." + method.name();
|
||||
qCDebug(dcJsonRpcTraffic()) << "Notification content:" << data;
|
||||
|
||||
foreach (const QUuid &clientId, m_clientNotifications.keys()) {
|
||||
if (m_clientNotifications.value(clientId).contains(handler->name())) {
|
||||
m_clientTransports.value(clientId)->sendData(clientId, data);
|
||||
}
|
||||
foreach (const QUuid &clientId, clientsToBeNotified) {
|
||||
qCDebug(dcJsonRpc()) << "Sending notification:" << handler->name() + "." + method.name();
|
||||
m_clientTransports.value(clientId)->sendData(clientId, data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -735,10 +763,19 @@ void JsonRPCServerImplementation::asyncReplyFinished()
|
||||
}
|
||||
if (!reply->timedOut()) {
|
||||
JsonValidator validator;
|
||||
Q_ASSERT_X(validator.validateReturns(reply->data(), reply->handler()->name() + '.' + reply->method(), m_api).success()
|
||||
QString method = reply->handler()->name() + '.' + reply->method();
|
||||
Q_ASSERT_X(validator.validateReturns(reply->data(), method, m_api).success()
|
||||
,validator.result().where().toUtf8()
|
||||
,validator.result().errorString().toUtf8() + "\nReturn value:\n" + QJsonDocument::fromVariant(reply->data()).toJson());
|
||||
sendResponse(interface, reply->clientId(), reply->commandId(), reply->data());
|
||||
|
||||
QString deprecationWarning;
|
||||
if (m_api.value("methods").toMap().value(method).toMap().contains("deprecated")) {
|
||||
deprecationWarning = m_api.value("methods").toMap().value(method).toMap().value("deprecated").toString();
|
||||
qCWarning(dcJsonRpc()) << "Client uses deprecated API. Please update client implementation!";
|
||||
qCWarning(dcJsonRpc()) << method + ':' << deprecationWarning;
|
||||
}
|
||||
|
||||
sendResponse(interface, reply->clientId(), reply->commandId(), reply->data(), deprecationWarning);
|
||||
} else {
|
||||
qCWarning(dcJsonRpc()) << "RPC call timed out:" << reply->handler()->name() << ":" << reply->method();
|
||||
sendErrorResponse(interface, reply->clientId(), reply->commandId(), "Command timed out");
|
||||
|
||||
@ -78,7 +78,7 @@ private:
|
||||
bool registerHandler(JsonHandler *handler);
|
||||
QHash<QString, JsonHandler *> handlers() const;
|
||||
|
||||
void sendResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QVariantMap ¶ms = QVariantMap());
|
||||
void sendResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QVariantMap ¶ms = QVariantMap(), const QString &deprecationWarning = QString());
|
||||
void sendErrorResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QString &error);
|
||||
void sendUnauthorizedResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QString &error);
|
||||
QVariantMap createWelcomeMessage(TransportInterface *interface, const QUuid &clientId) const;
|
||||
|
||||
@ -307,7 +307,6 @@ QVariant JsonHandler::pack(const QMetaObject &metaObject, const void *value) con
|
||||
|
||||
// Manually converting QList<int>... Only QVariantList is known to the meta system
|
||||
if (propertyTypeName.startsWith("QList<int>")) {
|
||||
qWarning() << "Packing list" << metaProperty.name() << propertyValue.toList();
|
||||
QVariantList list;
|
||||
foreach (int entry, propertyValue.value<QList<int>>()) {
|
||||
list << entry;
|
||||
@ -350,7 +349,6 @@ QVariant JsonHandler::unpack(const QMetaObject &metaObject, const QVariant &valu
|
||||
|
||||
// If it's a list object, loop over count
|
||||
if (m_listMetaObjects.contains(typeName)) {
|
||||
qWarning() << "** Unpacking" << typeName;
|
||||
if (value.type() != QVariant::List) {
|
||||
qCWarning(dcJsonRpc()) << "Cannot unpack" << typeName << ". Value is not in list format:" << value;
|
||||
return QVariant();
|
||||
@ -367,7 +365,6 @@ QVariant JsonHandler::unpack(const QMetaObject &metaObject, const QVariant &valu
|
||||
|
||||
foreach (const QVariant &variant, list) {
|
||||
QVariant value = unpack(entryMetaObject, variant);
|
||||
qWarning() << "Putting" << value << putMethod.name() << ptr << typeId;
|
||||
putMethod.invokeOnGadget(ptr, Q_ARG(QVariant, value));
|
||||
}
|
||||
|
||||
@ -378,7 +375,6 @@ QVariant JsonHandler::unpack(const QMetaObject &metaObject, const QVariant &valu
|
||||
|
||||
// if it's an object, loop over all properties
|
||||
if (m_metaObjects.contains(typeName)) {
|
||||
qWarning() << "*** Unpacking" << typeName;
|
||||
QVariantMap map = value.toMap();
|
||||
int typeId = QMetaType::type(metaObject.className());
|
||||
Q_ASSERT_X(typeId != 0, this->metaObject()->className(), QString("Cannot handle unregistered meta type %1").arg(typeName).toUtf8());
|
||||
@ -403,7 +399,6 @@ QVariant JsonHandler::unpack(const QMetaObject &metaObject, const QVariant &valu
|
||||
// recurse into child lists
|
||||
if (m_listMetaObjects.contains(propertyTypeName)) {
|
||||
QMetaObject propertyMetaObject = m_listMetaObjects.value(propertyTypeName);
|
||||
qWarning() << "Entering list object" << propertyTypeName << propertyMetaObject.className();
|
||||
metaProperty.writeOnGadget(ptr, unpack(propertyMetaObject, variant));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -304,6 +304,7 @@
|
||||
},
|
||||
"methods": {
|
||||
"Actions.ExecuteAction": {
|
||||
"deprecated": "Please use Devices.ExecuteAction instead.",
|
||||
"description": "Execute a single action.",
|
||||
"params": {
|
||||
"actionTypeId": "Uuid",
|
||||
@ -316,6 +317,7 @@
|
||||
}
|
||||
},
|
||||
"Actions.ExecuteBrowserItem": {
|
||||
"deprecated": "Please use Devices.ExecuteBrowserItem instead.",
|
||||
"description": "Execute the item identified by itemId on the given device.",
|
||||
"params": {
|
||||
"deviceId": "Uuid",
|
||||
@ -326,6 +328,7 @@
|
||||
}
|
||||
},
|
||||
"Actions.ExecuteBrowserItemAction": {
|
||||
"deprecated": "Please use Devices.ExecuteBrowserItem instead.",
|
||||
"description": "Execute the action for the browser item identified by actionTypeId and the itemId on the given device.",
|
||||
"params": {
|
||||
"actionTypeId": "Uuid",
|
||||
@ -338,7 +341,8 @@
|
||||
}
|
||||
},
|
||||
"Actions.GetActionType": {
|
||||
"description": "Get the ActionType for the given ActionTypeId",
|
||||
"deprecated": "Please use the Devices namespace instead.",
|
||||
"description": "Get the ActionType for the given ActionTypeId.",
|
||||
"params": {
|
||||
"actionTypeId": "Uuid"
|
||||
},
|
||||
@ -599,6 +603,40 @@
|
||||
"deviceError": "$ref:DeviceError"
|
||||
}
|
||||
},
|
||||
"Devices.ExecuteAction": {
|
||||
"description": "Execute a single action.",
|
||||
"params": {
|
||||
"actionTypeId": "Uuid",
|
||||
"deviceId": "Uuid",
|
||||
"o:params": "$ref:ParamList"
|
||||
},
|
||||
"returns": {
|
||||
"deviceError": "$ref:DeviceError",
|
||||
"o:displayMessage": "String"
|
||||
}
|
||||
},
|
||||
"Devices.ExecuteBrowserItem": {
|
||||
"description": "Execute the item identified by itemId on the given device.",
|
||||
"params": {
|
||||
"deviceId": "Uuid",
|
||||
"itemId": "String"
|
||||
},
|
||||
"returns": {
|
||||
"deviceError": "$ref:DeviceError"
|
||||
}
|
||||
},
|
||||
"Devices.ExecuteBrowserItemAction": {
|
||||
"description": "Execute the action for the browser item identified by actionTypeId and the itemId on the given device.",
|
||||
"params": {
|
||||
"actionTypeId": "Uuid",
|
||||
"deviceId": "Uuid",
|
||||
"itemId": "String",
|
||||
"o:params": "$ref:ParamList"
|
||||
},
|
||||
"returns": {
|
||||
"deviceError": "$ref:DeviceError"
|
||||
}
|
||||
},
|
||||
"Devices.GetActionTypes": {
|
||||
"description": "Get action types for a specified deviceClassId.",
|
||||
"params": {
|
||||
@ -784,6 +822,7 @@
|
||||
}
|
||||
},
|
||||
"Events.GetEventType": {
|
||||
"deprecated": "Please use the Devices namespace instead.",
|
||||
"description": "Get the EventType for the given eventTypeId.",
|
||||
"params": {
|
||||
"eventTypeId": "Uuid"
|
||||
@ -1185,6 +1224,7 @@
|
||||
}
|
||||
},
|
||||
"States.GetStateType": {
|
||||
"deprecated": "Please use the Devices namespace instead.",
|
||||
"description": "Get the StateType for the given stateTypeId.",
|
||||
"params": {
|
||||
"stateTypeId": "Uuid"
|
||||
@ -1441,6 +1481,12 @@
|
||||
"value": "Variant"
|
||||
}
|
||||
},
|
||||
"Devices.EventTriggered": {
|
||||
"description": "Emitted whenever an Event is triggered.",
|
||||
"params": {
|
||||
"event": "$ref:Event"
|
||||
}
|
||||
},
|
||||
"Devices.PluginConfigurationChanged": {
|
||||
"description": "Emitted whenever a plugin's configuration is changed.",
|
||||
"params": {
|
||||
@ -1457,6 +1503,7 @@
|
||||
}
|
||||
},
|
||||
"Events.EventTriggered": {
|
||||
"deprecated": "Please use Devices.EventTriggered instead.",
|
||||
"description": "Emitted whenever an Event is triggered.",
|
||||
"params": {
|
||||
"event": "$ref:Event"
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
#include "devices/devicediscoveryinfo.h"
|
||||
#include "devices/devicesetupinfo.h"
|
||||
|
||||
#include "servers/mocktcpserver.h"
|
||||
|
||||
using namespace nymeaserver;
|
||||
|
||||
class TestDevices : public NymeaTestBase
|
||||
@ -117,6 +119,14 @@ private slots:
|
||||
void testExecuteBrowserItemAction_data();
|
||||
void testExecuteBrowserItemAction();
|
||||
|
||||
void executeAction_data();
|
||||
void executeAction();
|
||||
|
||||
void triggerEvent();
|
||||
void triggerStateChangeEvent();
|
||||
|
||||
void params();
|
||||
|
||||
// Keep those at last as they will remove devices
|
||||
void removeDevice_data();
|
||||
void removeDevice();
|
||||
@ -1777,6 +1787,181 @@ void TestDevices::testExecuteBrowserItemAction()
|
||||
|
||||
}
|
||||
|
||||
void TestDevices::executeAction_data()
|
||||
{
|
||||
QTest::addColumn<DeviceId>("deviceId");
|
||||
QTest::addColumn<ActionTypeId>("actionTypeId");
|
||||
QTest::addColumn<QVariantList>("actionParams");
|
||||
QTest::addColumn<Device::DeviceError>("error");
|
||||
|
||||
QVariantList params;
|
||||
QVariantMap param1;
|
||||
param1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId);
|
||||
param1.insert("value", 5);
|
||||
params.append(param1);
|
||||
QVariantMap param2;
|
||||
param2.insert("paramTypeId", mockWithParamsActionParam2ParamTypeId);
|
||||
param2.insert("value", true);
|
||||
params.append(param2);
|
||||
|
||||
QTest::newRow("valid action") << m_mockDeviceId << mockWithParamsActionTypeId << params << Device::DeviceErrorNoError;
|
||||
QTest::newRow("invalid deviceId") << DeviceId::createDeviceId() << mockWithParamsActionTypeId << params << Device::DeviceErrorDeviceNotFound;
|
||||
QTest::newRow("invalid actionTypeId") << m_mockDeviceId << ActionTypeId::createActionTypeId() << params << Device::DeviceErrorActionTypeNotFound;
|
||||
QTest::newRow("missing params") << m_mockDeviceId << mockWithParamsActionTypeId << QVariantList() << Device::DeviceErrorMissingParameter;
|
||||
QTest::newRow("async action") << m_mockDeviceId << mockAsyncActionTypeId << QVariantList() << Device::DeviceErrorNoError;
|
||||
QTest::newRow("broken action") << m_mockDeviceId << mockFailingActionTypeId << QVariantList() << Device::DeviceErrorSetupFailed;
|
||||
QTest::newRow("async broken action") << m_mockDeviceId << mockAsyncFailingActionTypeId << QVariantList() << Device::DeviceErrorSetupFailed;
|
||||
}
|
||||
|
||||
void TestDevices::executeAction()
|
||||
{
|
||||
QFETCH(DeviceId, deviceId);
|
||||
QFETCH(ActionTypeId, actionTypeId);
|
||||
QFETCH(QVariantList, actionParams);
|
||||
QFETCH(Device::DeviceError, error);
|
||||
|
||||
QVariantMap params;
|
||||
params.insert("actionTypeId", actionTypeId);
|
||||
params.insert("deviceId", deviceId);
|
||||
params.insert("params", actionParams);
|
||||
QVariant response = injectAndWait("Devices.ExecuteAction", params);
|
||||
qDebug() << "executeActionresponse" << response;
|
||||
verifyError(response, "deviceError", enumValueName(error));
|
||||
|
||||
// Fetch action execution history from mock device
|
||||
QNetworkAccessManager nam;
|
||||
QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*)));
|
||||
|
||||
QNetworkRequest request(QUrl(QString("http://localhost:%1/actionhistory").arg(m_mockDevice1Port)));
|
||||
QNetworkReply *reply = nam.get(request);
|
||||
spy.wait();
|
||||
QCOMPARE(spy.count(), 1);
|
||||
reply->deleteLater();
|
||||
QByteArray data = reply->readAll();
|
||||
|
||||
if (error == Device::DeviceErrorNoError) {
|
||||
QVERIFY2(actionTypeId == ActionTypeId(data), QString("ActionTypeId mismatch. Got %1, Expected: %2")
|
||||
.arg(ActionTypeId(data).toString()).arg(actionTypeId.toString()).toLatin1().data());
|
||||
} else {
|
||||
QVERIFY2(data.length() == 0, QString("Data is %1, should be empty.").arg(QString(data)).toLatin1().data());
|
||||
}
|
||||
|
||||
// cleanup for the next run
|
||||
spy.clear();
|
||||
request.setUrl(QUrl(QString("http://localhost:%1/clearactionhistory").arg(m_mockDevice1Port)));
|
||||
reply = nam.get(request);
|
||||
spy.wait();
|
||||
QCOMPARE(spy.count(), 1);
|
||||
reply->deleteLater();
|
||||
|
||||
spy.clear();
|
||||
request.setUrl(QUrl(QString("http://localhost:%1/actionhistory").arg(m_mockDevice1Port)));
|
||||
reply = nam.get(request);
|
||||
spy.wait();
|
||||
QCOMPARE(spy.count(), 1);
|
||||
reply->deleteLater();
|
||||
data = reply->readAll();
|
||||
qDebug() << "cleared data:" << data;
|
||||
|
||||
}
|
||||
|
||||
void TestDevices::triggerEvent()
|
||||
{
|
||||
enableNotifications({"Devices"});
|
||||
QList<Device*> devices = NymeaCore::instance()->deviceManager()->findConfiguredDevices(mockDeviceClassId);
|
||||
QVERIFY2(devices.count() > 0, "There needs to be at least one configured Mock Device for this test");
|
||||
Device *device = devices.first();
|
||||
|
||||
|
||||
QSignalSpy spy(NymeaCore::instance(), SIGNAL(eventTriggered(const Event&)));
|
||||
QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
|
||||
|
||||
// Setup connection to mock client
|
||||
QNetworkAccessManager nam;
|
||||
|
||||
// trigger event in mock device
|
||||
int port = device->paramValue(mockDeviceHttpportParamTypeId).toInt();
|
||||
QNetworkRequest request(QUrl(QString("http://localhost:%1/generateevent?eventtypeid=%2").arg(port).arg(mockEvent1EventTypeId.toString())));
|
||||
QNetworkReply *reply = nam.get(request);
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
|
||||
// Lets wait for the notification
|
||||
spy.wait();
|
||||
QVERIFY(spy.count() > 0);
|
||||
for (int i = 0; i < spy.count(); i++ ){
|
||||
Event event = spy.at(i).at(0).value<Event>();
|
||||
if (event.deviceId() == device->id()) {
|
||||
// Make sure the event contains all the stuff we expect
|
||||
QCOMPARE(event.eventTypeId(), mockEvent1EventTypeId);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for the notification on JSON API
|
||||
QVariantList notifications;
|
||||
notifications = checkNotifications(notificationSpy, "Devices.EventTriggered");
|
||||
QVERIFY2(notifications.count() == 1, "Should get Devices.EventTriggered notification");
|
||||
QVariantMap notificationContent = notifications.first().toMap().value("params").toMap();
|
||||
|
||||
QCOMPARE(notificationContent.value("event").toMap().value("deviceId").toUuid().toString(), device->id().toString());
|
||||
QCOMPARE(notificationContent.value("event").toMap().value("eventTypeId").toUuid().toString(), mockEvent1EventTypeId.toString());
|
||||
}
|
||||
|
||||
void TestDevices::triggerStateChangeEvent()
|
||||
{
|
||||
enableNotifications({"Devices"});
|
||||
|
||||
QList<Device*> devices = NymeaCore::instance()->deviceManager()->findConfiguredDevices(mockDeviceClassId);
|
||||
QVERIFY2(devices.count() > 0, "There needs to be at least one configured Mock Device for this test");
|
||||
Device *device = devices.first();
|
||||
|
||||
QSignalSpy spy(NymeaCore::instance(), SIGNAL(eventTriggered(const Event&)));
|
||||
QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
|
||||
|
||||
// Setup connection to mock client
|
||||
QNetworkAccessManager nam;
|
||||
|
||||
// trigger state changed event in mock device
|
||||
int port = device->paramValue(mockDeviceHttpportParamTypeId).toInt();
|
||||
QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(port).arg(mockIntStateTypeId.toString()).arg(11)));
|
||||
QNetworkReply *reply = nam.get(request);
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
|
||||
// Lets wait for the notification
|
||||
spy.wait();
|
||||
QVERIFY(spy.count() > 0);
|
||||
for (int i = 0; i < spy.count(); i++ ){
|
||||
Event event = spy.at(i).at(0).value<Event>();
|
||||
if (event.deviceId() == device->id()) {
|
||||
// Make sure the event contains all the stuff we expect
|
||||
QCOMPARE(event.eventTypeId().toString(), mockIntStateTypeId.toString());
|
||||
QCOMPARE(event.param(ParamTypeId(mockIntStateTypeId.toString())).value().toInt(), 11);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for the notification on JSON API
|
||||
QVariantList notifications;
|
||||
notifications = checkNotifications(notificationSpy, "Devices.EventTriggered");
|
||||
QVERIFY2(notifications.count() == 1, "Should get Devices.EventTriggered notification");
|
||||
QVariantMap notificationContent = notifications.first().toMap().value("params").toMap();
|
||||
|
||||
QCOMPARE(notificationContent.value("event").toMap().value("deviceId").toUuid().toString(), device->id().toString());
|
||||
QCOMPARE(notificationContent.value("event").toMap().value("eventTypeId").toUuid().toString(), mockIntEventTypeId.toString());
|
||||
|
||||
}
|
||||
|
||||
void TestDevices::params()
|
||||
{
|
||||
Event event;
|
||||
ParamList params;
|
||||
ParamTypeId id = ParamTypeId::createParamTypeId();
|
||||
Param p(id, "foo bar");
|
||||
params.append(p);
|
||||
event.setParams(params);
|
||||
|
||||
QVERIFY(event.param(id).value().toString() == "foo bar");
|
||||
QVERIFY(!event.param(ParamTypeId::createParamTypeId()).value().isValid());
|
||||
}
|
||||
|
||||
#include "testdevices.moc"
|
||||
QTEST_MAIN(TestDevices)
|
||||
|
||||
|
||||
@ -22,6 +22,8 @@
|
||||
#include "nymeatestbase.h"
|
||||
#include "nymeacore.h"
|
||||
|
||||
#include "servers/mocktcpserver.h"
|
||||
|
||||
using namespace nymeaserver;
|
||||
|
||||
class TestEvents: public NymeaTestBase
|
||||
@ -40,11 +42,14 @@ private slots:
|
||||
|
||||
void TestEvents::triggerEvent()
|
||||
{
|
||||
enableNotifications({"Events"});
|
||||
|
||||
QList<Device*> devices = NymeaCore::instance()->deviceManager()->findConfiguredDevices(mockDeviceClassId);
|
||||
QVERIFY2(devices.count() > 0, "There needs to be at least one configured Mock Device for this test");
|
||||
Device *device = devices.first();
|
||||
|
||||
QSignalSpy spy(NymeaCore::instance(), SIGNAL(eventTriggered(const Event&)));
|
||||
QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
|
||||
|
||||
// Setup connection to mock client
|
||||
QNetworkAccessManager nam;
|
||||
@ -65,15 +70,28 @@ void TestEvents::triggerEvent()
|
||||
QCOMPARE(event.eventTypeId(), mockEvent1EventTypeId);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for the notification on JSON API
|
||||
QVariantList notifications;
|
||||
notifications = checkNotifications(notificationSpy, "Events.EventTriggered");
|
||||
QVERIFY2(notifications.count() == 1, "Should get Events.EventTriggered notification");
|
||||
QVERIFY2(notifications.first().toMap().contains("deprecationWarning"), "Deprecation warning not included in notification");
|
||||
|
||||
QVariantMap notificationContent = notifications.first().toMap().value("params").toMap();
|
||||
QCOMPARE(notificationContent.value("event").toMap().value("deviceId").toUuid().toString(), device->id().toString());
|
||||
QCOMPARE(notificationContent.value("event").toMap().value("eventTypeId").toUuid().toString(), mockEvent1EventTypeId.toString());
|
||||
}
|
||||
|
||||
void TestEvents::triggerStateChangeEvent()
|
||||
{
|
||||
enableNotifications({"Events"});
|
||||
|
||||
QList<Device*> devices = NymeaCore::instance()->deviceManager()->findConfiguredDevices(mockDeviceClassId);
|
||||
QVERIFY2(devices.count() > 0, "There needs to be at least one configured Mock Device for this test");
|
||||
Device *device = devices.first();
|
||||
|
||||
QSignalSpy spy(NymeaCore::instance(), SIGNAL(eventTriggered(const Event&)));
|
||||
QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
|
||||
|
||||
// Setup connection to mock client
|
||||
QNetworkAccessManager nam;
|
||||
@ -95,6 +113,17 @@ void TestEvents::triggerStateChangeEvent()
|
||||
QCOMPARE(event.param(ParamTypeId(mockIntStateTypeId.toString())).value().toInt(), 11);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for the notification on JSON API
|
||||
QVariantList notifications;
|
||||
notifications = checkNotifications(notificationSpy, "Events.EventTriggered");
|
||||
QVERIFY2(notifications.count() == 1, "Should get Devices.EventTriggered notification");
|
||||
QVERIFY2(notifications.first().toMap().contains("deprecationWarning"), "Deprecation warning not included in notification!");
|
||||
|
||||
QVariantMap notificationContent = notifications.first().toMap().value("params").toMap();
|
||||
|
||||
QCOMPARE(notificationContent.value("event").toMap().value("deviceId").toUuid().toString(), device->id().toString());
|
||||
QCOMPARE(notificationContent.value("event").toMap().value("eventTypeId").toUuid().toString(), mockIntEventTypeId.toString());
|
||||
}
|
||||
|
||||
void TestEvents::params()
|
||||
@ -130,6 +159,9 @@ void TestEvents::getEventType()
|
||||
|
||||
verifyError(response, "deviceError", enumValueName(error));
|
||||
|
||||
qCDebug(dcTests()) << "*content" << response;
|
||||
QVERIFY2(response.toMap().contains("deprecationWarning"), "Deprecation warning not shown in reply");
|
||||
|
||||
if (error == Device::DeviceErrorNoError) {
|
||||
QVERIFY2(EventTypeId(response.toMap().value("params").toMap().value("eventType").toMap().value("id").toString()) == eventTypeId, "Didn't get a reply for the same actionTypeId as requested.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user