diff --git a/libguh/devicemanager.cpp b/libguh/devicemanager.cpp index d5138466..b8f86d6a 100644 --- a/libguh/devicemanager.cpp +++ b/libguh/devicemanager.cpp @@ -86,6 +86,7 @@ #include #include #include +#include /*! Constructs the DeviceManager with the given \a parent. There should only be one DeviceManager in the system created by \l{GuhCore}. Use \c GuhCore::instance()->deviceManager() instead to access the DeviceManager. @@ -97,6 +98,8 @@ DeviceManager::DeviceManager(QObject *parent) : m_pluginTimer.setInterval(15000); connect(&m_pluginTimer, &QTimer::timeout, this, &DeviceManager::timerEvent); + m_settingsFile = QCoreApplication::instance()->organizationName() + "/devices"; + // Give hardware a chance to start up before loading plugins etc. QMetaObject::invokeMethod(this, "loadPlugins", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "loadConfiguredDevices", Qt::QueuedConnection); @@ -298,7 +301,7 @@ QPair DeviceManager::removeConfiguredDevice device->deleteLater(); - QSettings settings; + QSettings settings(m_settingsFile); settings.beginGroup("DeviceConfig"); settings.beginGroup(deviceId.toString()); settings.remove(""); @@ -406,7 +409,7 @@ void DeviceManager::loadPlugins() m_supportedDevices.insert(deviceClass.id(), deviceClass); qDebug() << "* Loaded device class:" << deviceClass.name(); } - QSettings settings; + QSettings settings(m_settingsFile); settings.beginGroup("PluginConfig"); QList params; if (settings.childGroups().contains(pluginIface->pluginId().toString())) { @@ -440,7 +443,7 @@ void DeviceManager::loadPlugins() void DeviceManager::loadConfiguredDevices() { - QSettings settings; + QSettings settings(m_settingsFile); settings.beginGroup("DeviceConfig"); qDebug() << "loading devices from" << settings.fileName(); foreach (const QString &idString, settings.childGroups()) { @@ -472,7 +475,7 @@ void DeviceManager::loadConfiguredDevices() void DeviceManager::storeConfiguredDevices() { - QSettings settings; + QSettings settings(m_settingsFile); settings.beginGroup("DeviceConfig"); foreach (Device *device, m_configuredDevices) { settings.beginGroup(device->id().toString()); diff --git a/libguh/devicemanager.h b/libguh/devicemanager.h index b24559d5..fefceb69 100644 --- a/libguh/devicemanager.h +++ b/libguh/devicemanager.h @@ -132,6 +132,8 @@ private: QHash m_devicePlugins; + QString m_settingsFile; + // Hardware Resources Radio433* m_radio433; QTimer m_pluginTimer; diff --git a/server/jsonrpc/jsontypes.cpp b/server/jsonrpc/jsontypes.cpp index 97474313..b53d3259 100644 --- a/server/jsonrpc/jsontypes.cpp +++ b/server/jsonrpc/jsontypes.cpp @@ -432,6 +432,9 @@ QVariantMap JsonTypes::packRule(const Rule &rule) Param JsonTypes::unpackParam(const QVariantMap ¶mMap) { + if (paramMap.keys().count() == 0) { + return Param(); + } QString key = paramMap.keys().first(); return Param(key, paramMap.value(key)); } diff --git a/server/jsonrpc/ruleshandler.cpp b/server/jsonrpc/ruleshandler.cpp index 725578a1..099bd4e3 100644 --- a/server/jsonrpc/ruleshandler.cpp +++ b/server/jsonrpc/ruleshandler.cpp @@ -38,8 +38,9 @@ RulesHandler::RulesHandler(QObject *parent) : setReturns("GetRules", returns); params.clear(); returns.clear(); - setDescription("AddRule", "Add a rule"); - params.insert("eventDescriptor", JsonTypes::eventDescriptorRef()); + setDescription("AddRule", "Add a rule."); + params.insert("o:eventDescriptor", JsonTypes::eventDescriptorRef()); + params.insert("o:eventDescriptorList", QVariantList() << JsonTypes::eventDescriptorRef()); QVariantList actions; actions.append(JsonTypes::actionRef()); params.insert("actions", actions); diff --git a/server/ruleengine.cpp b/server/ruleengine.cpp index a8f99717..69c28d0a 100644 --- a/server/ruleengine.cpp +++ b/server/ruleengine.cpp @@ -72,8 +72,8 @@ RuleEngine::RuleEngine(QObject *parent) : QObject(parent) { m_settingsFile = QCoreApplication::instance()->organizationName() + "/rules"; - qDebug() << "laoding rules from" << m_settingsFile; QSettings settings(m_settingsFile); + qDebug() << "laoding rules from" << settings.fileName(); foreach (const QString &idString, settings.childGroups()) { qDebug() << "found rule" << idString; @@ -133,8 +133,8 @@ RuleEngine::RuleEngine(QObject *parent) : settings.endGroup(); -// Rule rule = Rule(RuleId(idString), eventDescriptorList, states, actions); -// m_rules.append(rule); + Rule rule = Rule(RuleId(idString), eventDescriptorList, stateEvaluator, actions); + m_rules.append(rule); } } diff --git a/tests/auto/devices/testdevices.cpp b/tests/auto/devices/testdevices.cpp index 64cb5f84..94ebbcd3 100644 --- a/tests/auto/devices/testdevices.cpp +++ b/tests/auto/devices/testdevices.cpp @@ -278,12 +278,8 @@ void TestDevices::storedDevices() DeviceId addedDeviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); QVERIFY(!addedDeviceId.isNull()); - // Destroy and recreate the core instance to check if settings are loaded at startup - GuhCore::instance()->destroy(); - QSignalSpy spy(GuhCore::instance()->deviceManager(), SIGNAL(loaded())); - spy.wait(); - m_mockTcpServer = MockTcpServer::servers().first(); - + // Restart the core instance to check if settings are loaded at startup + restartServer(); response = injectAndWait("Devices.GetConfiguredDevices", QVariantMap()); diff --git a/tests/auto/guhtestbase.cpp b/tests/auto/guhtestbase.cpp index 23eac3dd..7435f63f 100644 --- a/tests/auto/guhtestbase.cpp +++ b/tests/auto/guhtestbase.cpp @@ -44,8 +44,10 @@ void GuhTestBase::initTestCase() { // If testcase asserts cleanup won't do. Lets clear any previous test run settings leftovers - QSettings settings; - settings.clear(); + QSettings rulesSettings(QCoreApplication::instance()->organizationName() + "/rules"); + rulesSettings.clear(); + QSettings deviceSettings(QCoreApplication::instance()->organizationName() + "/devices"); + deviceSettings.clear(); GuhCore::instance(); @@ -105,3 +107,12 @@ void GuhTestBase::verifySuccess(const QVariant &response, bool success) QVERIFY2(response.toMap().value("status").toString() == QString("success"), jsonDoc.toJson().data()); QVERIFY2(response.toMap().value("params").toMap().value("success").toBool() == success, jsonDoc.toJson().data()); } + +void GuhTestBase::restartServer() +{ + // Destroy and recreate the core instance... + GuhCore::instance()->destroy(); + QSignalSpy spy(GuhCore::instance()->deviceManager(), SIGNAL(loaded())); + spy.wait(); + m_mockTcpServer = MockTcpServer::servers().first(); +} diff --git a/tests/auto/guhtestbase.h b/tests/auto/guhtestbase.h index ac519c64..4c316253 100644 --- a/tests/auto/guhtestbase.h +++ b/tests/auto/guhtestbase.h @@ -58,6 +58,7 @@ protected slots: protected: QVariant injectAndWait(const QString &method, const QVariantMap ¶ms = QVariantMap()); void verifySuccess(const QVariant &response, bool success = true); + void restartServer(); protected: MockTcpServer *m_mockTcpServer; diff --git a/tests/auto/rules/testrules.cpp b/tests/auto/rules/testrules.cpp index e4709ba7..79f502e3 100644 --- a/tests/auto/rules/testrules.cpp +++ b/tests/auto/rules/testrules.cpp @@ -36,8 +36,8 @@ class TestRules: public GuhTestBase private slots: void addRules_data(); void addRules(); - void getStateValue_data(); - void getStateValue(); + + void loadStoreConfig(); }; void TestRules::addRules_data() @@ -117,34 +117,84 @@ void TestRules::addRules() QVERIFY2(rules.count() == 0, "There should be no rules."); } -void TestRules::getStateValue_data() +void TestRules::loadStoreConfig() { - QList devices = GuhCore::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(); + QVariantMap eventDescriptor1; + eventDescriptor1.insert("eventTypeId", mockEvent1Id); + eventDescriptor1.insert("deviceId", m_mockDeviceId); + eventDescriptor1.insert("paramDescriptors", QVariantList()); - QTest::addColumn("deviceId"); - QTest::addColumn("stateTypeId"); - QTest::addColumn("success"); + QVariantMap eventDescriptor2; + eventDescriptor2.insert("eventTypeId", mockEvent1Id); + eventDescriptor2.insert("deviceId", m_mockDeviceId); + eventDescriptor2.insert("paramDescriptors", QVariantList()); - QTest::newRow("existing state") << device->id() << mockIntStateId << true; - QTest::newRow("invalid device") << DeviceId::createDeviceId() << mockIntStateId << false; - QTest::newRow("invalid statetype") << device->id() << StateTypeId::createStateTypeId() << false; -} + QVariantMap action1; + action1.insert("actionTypeId", mockActionIdNoParams); + action1.insert("deviceId", m_mockDeviceId); + action1.insert("params", QVariantList()); + + QVariantMap action2; + action2.insert("actionTypeId", mockActionIdWithParams); + qDebug() << "got action id" << mockActionIdWithParams; + action2.insert("deviceId", m_mockDeviceId); + QVariantList action2Params; + QVariantMap action2Param1; + action2Param1.insert("mockActionParam1", 5); + action2Params.append(action2Param1); + QVariantMap action2Param2; + action2Param2.insert("mockActionParam2", true); + action2Params.append(action2Param2); + action2.insert("params", action2Params); -void TestRules::getStateValue() -{ - QFETCH(DeviceId, deviceId); - QFETCH(StateTypeId, stateTypeId); - QFETCH(bool, success); QVariantMap params; - params.insert("deviceId", deviceId.toString()); - params.insert("stateTypeId", stateTypeId.toString()); + QVariantList actions; + actions.append(action1); + actions.append(action2); + params.insert("actions", actions); + params.insert("eventDescriptor", eventDescriptor1); + QVariant response = injectAndWait("Rules.AddRule", params); - QVariant response = injectAndWait("Devices.GetStateValue", params); + RuleId newRuleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString()); + verifySuccess(response, true); - verifySuccess(response, success); + restartServer(); + + response = injectAndWait("Rules.GetRules"); + + QVariantList rules = response.toMap().value("params").toMap().value("rules").toList(); + + QVERIFY2(rules.count() == 1, "There should be exactly one rule"); + QCOMPARE(RuleId(rules.first().toMap().value("id").toString()), newRuleId); + + QVariantList eventDescriptors = rules.first().toMap().value("eventDescriptors").toList(); + QVERIFY2(eventDescriptors.count() == 1, "There shoud be exactly one eventDescriptor"); + QVERIFY2(eventDescriptors.first().toMap() == eventDescriptor1, "Event descriptor doesn't match"); + + QVariantList replyActions = rules.first().toMap().value("actions").toList(); + foreach (const QVariant &actionVariant, actions) { + bool found = false; + foreach (const QVariant &replyActionVariant, replyActions) { + if (actionVariant.toMap().value("actionTypeId") == replyActionVariant.toMap().value("actionTypeId") && + actionVariant.toMap().value("deviceId") == replyActionVariant.toMap().value("deviceId")) { + found = true; + QVERIFY2(actionVariant == replyActionVariant, "Action doesn't match after loading from config."); + } + } + QVERIFY2(found, "Action not found after loading from config."); + } + + params.clear(); + params.insert("ruleId", newRuleId); + response = injectAndWait("Rules.RemoveRule", params); + verifySuccess(response, true); + + restartServer(); + + response = injectAndWait("Rules.GetRules"); + rules = response.toMap().value("params").toMap().value("rules").toList(); + QVERIFY2(rules.count() == 0, "There should be no rules."); } #include "testrules.moc"