From f954f10d0fbc9b863248900a38b6eb77202e7bf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Sat, 12 Dec 2015 17:16:56 +0100 Subject: [PATCH] limit log db size for tests --- server/logging/logengine.cpp | 20 ++-- server/logging/logengine.h | 1 + server/logging/logentry.cpp | 48 +------- server/logging/logentry.h | 3 - tests/auto/logging/testlogging.cpp | 10 +- .../testrestdeviceclasses.cpp | 105 +++++++++++------- tests/auto/restrules/testrestrules.cpp | 32 ++++++ 7 files changed, 119 insertions(+), 100 deletions(-) diff --git a/server/logging/logengine.cpp b/server/logging/logengine.cpp index 9823584d..a0dbd0ba 100644 --- a/server/logging/logengine.cpp +++ b/server/logging/logengine.cpp @@ -105,6 +105,7 @@ #include "loggingcategories.h" #include "logging.h" +#include #include #include #include @@ -114,7 +115,6 @@ #include #define DB_SCHEMA_VERSION 2 -#define DB_MAX_SIZE 8000 namespace guhserver { @@ -122,9 +122,14 @@ namespace guhserver { LogEngine::LogEngine(QObject *parent): QObject(parent) { - m_db = QSqlDatabase::addDatabase("QSQLITE"); m_db.setDatabaseName(GuhSettings::logPath()); + m_dbMaxSize = 8000; + + if (QCoreApplication::instance()->organizationName() == "guh-test") { + m_dbMaxSize = 20; + qCDebug(dcLogEngine) << "Set logging dab max size to" << m_dbMaxSize << "for testing."; + } qCDebug(dcLogEngine) << "Opening logging database" << m_db.databaseName(); @@ -297,6 +302,7 @@ void LogEngine::appendLogEntry(const LogEntry &entry) QSqlQuery query; if (!query.exec(queryString)) { qCWarning(dcLogEngine) << "Error writing log entry. Driver error:" << query.lastError().driverText() << "Database error:" << query.lastError().databaseText(); + qCWarning(dcLogEngine) << entry; return; } @@ -317,10 +323,10 @@ void LogEngine::checkDBSize() numRows = query.at() + 1; } - if (numRows >= DB_MAX_SIZE) { - // keep only the latest DB_MAX_SIZE entries - qCDebug(dcLogEngine) << "Deleting oldest entries and keep only the latest" << DB_MAX_SIZE << "entries."; - QString queryDeleteString = QString("DELETE FROM entries WHERE ROWID IN (SELECT ROWID FROM entries ORDER BY timestamp DESC LIMIT -1 OFFSET %1);").arg(QString::number(DB_MAX_SIZE)); + if (numRows >= m_dbMaxSize) { + // keep only the latest m_dbMaxSize entries + qCDebug(dcLogEngine) << "Deleting oldest entries and keep only the latest" << m_dbMaxSize << "entries."; + QString queryDeleteString = QString("DELETE FROM entries WHERE ROWID IN (SELECT ROWID FROM entries ORDER BY timestamp DESC LIMIT -1 OFFSET %1);").arg(QString::number(m_dbMaxSize)); if (!query.exec(queryDeleteString)) { qCWarning(dcLogEngine) << "Error deleting oldest log entries to keep size. Driver error:" << query.lastError().driverText() << "Database error:" << query.lastError().databaseText(); } else { @@ -392,7 +398,7 @@ void LogEngine::initDB() qCWarning(dcLogEngine) << "Error creating log table in database. Driver error:" << query.lastError().driverText() << "Database error:" << query.lastError().databaseText(); } } - qCDebug(dcLogEngine) << "Initialized logging DB successfully."; + qCDebug(dcLogEngine) << "Initialized logging DB successfully. (maximum DB size:" << m_dbMaxSize << ")"; } } diff --git a/server/logging/logengine.h b/server/logging/logengine.h index 09781596..ea6663fa 100644 --- a/server/logging/logengine.h +++ b/server/logging/logengine.h @@ -49,6 +49,7 @@ signals: private: QSqlDatabase m_db; + int m_dbMaxSize; void initDB(); void appendLogEntry(const LogEntry &entry); diff --git a/server/logging/logentry.cpp b/server/logging/logentry.cpp index 07e6549f..3f278af7 100644 --- a/server/logging/logentry.cpp +++ b/server/logging/logentry.cpp @@ -76,41 +76,11 @@ Logging::LoggingLevel LogEntry::level() const return m_level; } -QString LogEntry::levelString() const -{ - switch (m_level) { - case Logging::LoggingLevelAlert: - return "LoggingLevelAlert"; - case Logging::LoggingLevelInfo: - return "LoggingLevelInfo"; - default: - return "< Unknown >"; - } -} - Logging::LoggingSource LogEntry::source() const { return m_source; } -QString LogEntry::sourceString() const -{ - switch (m_source) { - case Logging::LoggingSourceActions: - return "LoggingSourceActions"; - case Logging::LoggingSourceEvents: - return "LoggingSourceEvents"; - case Logging::LoggingSourceRules: - return "LoggingSourceRules"; - case Logging::LoggingSourceStates: - return "LoggingSourceStates"; - case Logging::LoggingSourceSystem: - return "LoggingSourceSystem"; - default: - return "< Unknown >"; - } -} - QUuid LogEntry::typeId() const { return m_typeId; @@ -145,18 +115,6 @@ Logging::LoggingEventType LogEntry::eventType() const return m_eventType; } -QString LogEntry::eventTypeString() const -{ - switch (m_eventType) { - case Logging::LoggingEventTypeActiveChange: - return "LoggingEventTypeActiveChange"; - case Logging::LoggingEventTypeTrigger: - return "LoggingEventTypeTrigger"; - default: - return "< Unknown >"; - } -} - bool LogEntry::active() const { return m_active; @@ -179,9 +137,9 @@ QDebug operator<<(QDebug dbg, const LogEntry &entry) dbg.nospace() << " time stamp: " << entry.timestamp().toTime_t() << endl; dbg.nospace() << " DeviceId: " << entry.deviceId().toString() << endl; dbg.nospace() << " type id: " << entry.typeId().toString() << endl; - dbg.nospace() << " source: " << entry.sourceString() << endl; - dbg.nospace() << " level: " << entry.levelString() << endl; - dbg.nospace() << " eventType: " << entry.eventTypeString() << endl; + dbg.nospace() << " source: " << JsonTypes::loggingSourceToString(entry.source()) << endl; + dbg.nospace() << " level: " << JsonTypes::loggingLevelToString(entry.level()) << endl; + dbg.nospace() << " eventType: " << JsonTypes::loggingEventTypeToString(entry.eventType()) << endl; dbg.nospace() << " error code: " << entry.errorCode() << endl; dbg.nospace() << " active: " << entry.active() << endl; dbg.nospace() << " value: " << entry.value() << endl; diff --git a/server/logging/logentry.h b/server/logging/logentry.h index fb6267f9..3a0075ed 100644 --- a/server/logging/logentry.h +++ b/server/logging/logentry.h @@ -42,11 +42,8 @@ public: // Valid for all LoggingSources QDateTime timestamp() const; Logging::LoggingLevel level() const; - QString levelString() const; Logging::LoggingSource source() const; - QString sourceString() const; Logging::LoggingEventType eventType() const; - QString eventTypeString() const; // Valid for LoggingSourceStates, LoggingSourceEvents, LoggingSourceActions, LoggingSourceRules QUuid typeId() const; diff --git a/tests/auto/logging/testlogging.cpp b/tests/auto/logging/testlogging.cpp index d2ac8979..0f39046e 100644 --- a/tests/auto/logging/testlogging.cpp +++ b/tests/auto/logging/testlogging.cpp @@ -127,12 +127,10 @@ void TestLogging::invalidFilter() QFETCH(QVariantMap, filter); QVariant response = injectAndWait("Logging.GetLogEntries", filter); QVERIFY(!response.isNull()); - //qDebug() << QJsonDocument::fromVariant(response).toJson(); // verify json error QVERIFY(response.toMap().value("status").toString() == "error"); qDebug() << response.toMap().value("error").toString(); - } @@ -213,7 +211,7 @@ void TestLogging::actionLog() QVariant response = injectAndWait("Actions.ExecuteAction", params); verifyDeviceError(response); - // Lets wait for the notification + // Lets wait 3for the notification clientSpy.wait(200); QVariant notification = checkNotification(clientSpy, "Logging.LogEntryAdded"); QVERIFY(!notification.isNull()); @@ -249,7 +247,7 @@ void TestLogging::actionLog() verifyLoggingError(response); QVariantList logEntries = response.toMap().value("params").toMap().value("logEntries").toList(); - QVERIFY(logEntries.count() == 1); + QCOMPARE(logEntries.count(), 1); // EXECUTE broken action params.clear(); clientSpy.clear(); @@ -283,7 +281,7 @@ void TestLogging::actionLog() verifyLoggingError(response); logEntries = response.toMap().value("params").toMap().value("logEntries").toList(); - QVERIFY(logEntries.count() == 1); + QCOMPARE(logEntries.count(), 1); // check different filters params.clear(); @@ -296,7 +294,7 @@ void TestLogging::actionLog() verifyLoggingError(response); logEntries = response.toMap().value("params").toMap().value("logEntries").toList(); - QVERIFY(logEntries.count() == 1); + QCOMPARE(logEntries.count(), 1); params.clear(); params.insert("deviceIds", QVariantList() << m_mockDeviceId); diff --git a/tests/auto/restdeviceclasses/testrestdeviceclasses.cpp b/tests/auto/restdeviceclasses/testrestdeviceclasses.cpp index 63780917..4b80a8d8 100644 --- a/tests/auto/restdeviceclasses/testrestdeviceclasses.cpp +++ b/tests/auto/restdeviceclasses/testrestdeviceclasses.cpp @@ -44,6 +44,7 @@ class TestRestDeviceClasses: public GuhTestBase private slots: void getSupportedDevices(); + void getActionTypes_data(); void getActionTypes(); @@ -63,7 +64,8 @@ private slots: void TestRestDeviceClasses::getSupportedDevices() { // Get all deviceclasses - QVariant response = getAndWait(QNetworkRequest(QUrl("http://localhost:3333/api/v1/deviceclasses"))); + QUrl url("http://localhost:3333/api/v1/deviceclasses"); + QVariant response = getAndWait(QNetworkRequest(url)); QVariantList deviceClassesList = response.toList(); QVERIFY2(deviceClassesList.count() > 0, "Not enought deviceclasses."); @@ -77,37 +79,49 @@ void TestRestDeviceClasses::getSupportedDevices() response = getAndWait(request); QVERIFY2(!response.isNull(), "Could not get device"); } + + QUrlQuery query; + query.addQueryItem("vendorId", guhVendorId.toString()); + url.setQuery(query); + + response = getAndWait(QNetworkRequest(url)); + deviceClassesList = response.toList(); + QVERIFY2(deviceClassesList.count() > 0, "Not enought deviceclasses."); + } void TestRestDeviceClasses::getActionTypes_data() { - QTest::addColumn("deviceClassId"); - QTest::addColumn("actionTypeId"); + QTest::addColumn("deviceClassId"); + QTest::addColumn("actionTypeId"); QTest::addColumn("expectedStatusCode"); QTest::addColumn("error"); - QTest::newRow("all ActionTypes") << mockDeviceClassId << ActionTypeId() << 200 << DeviceManager::DeviceErrorNoError; - QTest::newRow("ActionType async") << mockDeviceClassId << mockActionIdAsync << 200 << DeviceManager::DeviceErrorNoError; - QTest::newRow("ActionType no params") << mockDeviceClassId << mockActionIdNoParams << 200 << DeviceManager::DeviceErrorNoError; - QTest::newRow("ActionType failing") << mockDeviceClassId << mockActionIdFailing << 200 << DeviceManager::DeviceErrorNoError; - QTest::newRow("ActionType with params") << mockDeviceClassId << mockActionIdWithParams << 200 << DeviceManager::DeviceErrorNoError; - QTest::newRow("invalid DeviceClassId") << DeviceClassId::createDeviceClassId() << mockActionIdNoParams << 404 << DeviceManager::DeviceErrorDeviceClassNotFound; - QTest::newRow("invalid ActionTypeId") << mockDeviceClassId << ActionTypeId::createActionTypeId() << 404 << DeviceManager::DeviceErrorActionTypeNotFound; + QTest::newRow("all ActionTypes") << mockDeviceClassId.toString() << QString() << 200 << DeviceManager::DeviceErrorNoError; + QTest::newRow("ActionType async") << mockDeviceClassId.toString() << mockActionIdAsync.toString() << 200 << DeviceManager::DeviceErrorNoError; + QTest::newRow("ActionType no params") << mockDeviceClassId.toString() << mockActionIdNoParams.toString() << 200 << DeviceManager::DeviceErrorNoError; + QTest::newRow("ActionType failing") << mockDeviceClassId.toString() << mockActionIdFailing.toString() << 200 << DeviceManager::DeviceErrorNoError; + QTest::newRow("ActionType with params") << mockDeviceClassId.toString() << mockActionIdWithParams.toString() << 200 << DeviceManager::DeviceErrorNoError; + QTest::newRow("invalid DeviceClassId") << DeviceClassId::createDeviceClassId().toString() << mockActionIdNoParams.toString() << 404 << DeviceManager::DeviceErrorDeviceClassNotFound; + QTest::newRow("invalid ActionTypeId") << mockDeviceClassId.toString() << ActionTypeId::createActionTypeId().toString() << 404 << DeviceManager::DeviceErrorActionTypeNotFound; + QTest::newRow("invalid ActionTypeId format") << mockDeviceClassId.toString() << "uuid" << 400 << DeviceManager::DeviceErrorActionTypeNotFound; + QTest::newRow("invalid DeviceClassId format") << "uuid" << "uuid" << 400 << DeviceManager::DeviceErrorDeviceClassNotFound; + } void TestRestDeviceClasses::getActionTypes() { - QFETCH(DeviceClassId, deviceClassId); - QFETCH(ActionTypeId, actionTypeId); + QFETCH(QString, deviceClassId); + QFETCH(QString, actionTypeId); QFETCH(int, expectedStatusCode); QFETCH(DeviceManager::DeviceError, error); QNetworkRequest request; - if (!actionTypeId.isNull()) { - request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/actiontypes/%2").arg(deviceClassId.toString()).arg(actionTypeId.toString()))); + if (!actionTypeId.isEmpty()) { + request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/actiontypes/%2").arg(deviceClassId).arg(actionTypeId))); } else { // Get all actiontypes - request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/actiontypes").arg(deviceClassId.toString()))); + request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/actiontypes").arg(deviceClassId))); } QVariant response = getAndWait(request, expectedStatusCode); @@ -119,31 +133,33 @@ void TestRestDeviceClasses::getActionTypes() void TestRestDeviceClasses::getStateTypes_data() { - QTest::addColumn("deviceClassId"); - QTest::addColumn("stateTypeId"); + QTest::addColumn("deviceClassId"); + QTest::addColumn("stateTypeId"); QTest::addColumn("expectedStatusCode"); QTest::addColumn("error"); - QTest::newRow("all ActionTypes") << mockDeviceClassId << StateTypeId() << 200 << DeviceManager::DeviceErrorNoError; - QTest::newRow("StateType bool") << mockDeviceClassId << mockBoolStateId << 200 << DeviceManager::DeviceErrorNoError; - QTest::newRow("StateType int") << mockDeviceClassId << mockIntStateId << 200 << DeviceManager::DeviceErrorNoError; - QTest::newRow("invalid DeviceClassId") << DeviceClassId::createDeviceClassId() << mockBoolStateId << 404 << DeviceManager::DeviceErrorDeviceClassNotFound; - QTest::newRow("invalid StateTypeId") << mockDeviceClassId << StateTypeId::createStateTypeId() << 404 << DeviceManager::DeviceErrorStateTypeNotFound; + QTest::newRow("all ActionTypes") << mockDeviceClassId.toString() << QString() << 200 << DeviceManager::DeviceErrorNoError; + QTest::newRow("StateType bool") << mockDeviceClassId.toString() << mockBoolStateId.toString() << 200 << DeviceManager::DeviceErrorNoError; + QTest::newRow("StateType int") << mockDeviceClassId.toString() << mockIntStateId.toString() << 200 << DeviceManager::DeviceErrorNoError; + QTest::newRow("invalid DeviceClassId") << DeviceClassId::createDeviceClassId().toString() << mockBoolStateId.toString() << 404 << DeviceManager::DeviceErrorDeviceClassNotFound; + QTest::newRow("invalid StateTypeId") << mockDeviceClassId.toString() << StateTypeId::createStateTypeId().toString() << 404 << DeviceManager::DeviceErrorStateTypeNotFound; + QTest::newRow("invalid StateTypeId format") << mockDeviceClassId.toString() << "uuid" << 400 << DeviceManager::DeviceErrorStateTypeNotFound; + QTest::newRow("invalid DeviceClassId format") << "uuid" << "uuid" << 400 << DeviceManager::DeviceErrorDeviceClassNotFound; } void TestRestDeviceClasses::getStateTypes() { - QFETCH(DeviceClassId, deviceClassId); - QFETCH(StateTypeId, stateTypeId); + QFETCH(QString, deviceClassId); + QFETCH(QString, stateTypeId); QFETCH(int, expectedStatusCode); QFETCH(DeviceManager::DeviceError, error); QNetworkRequest request; - if (!stateTypeId.isNull()) { - request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/statetypes/%2").arg(deviceClassId.toString()).arg(stateTypeId.toString()))); + if (!stateTypeId.isEmpty()) { + request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/statetypes/%2").arg(deviceClassId).arg(stateTypeId))); } else { // Get all actiontypes - request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/statetypes").arg(deviceClassId.toString()))); + request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/statetypes").arg(deviceClassId))); } QVariant response = getAndWait(request, expectedStatusCode); @@ -155,31 +171,33 @@ void TestRestDeviceClasses::getStateTypes() void TestRestDeviceClasses::getEventTypes_data() { - QTest::addColumn("deviceClassId"); - QTest::addColumn("eventTypeId"); + QTest::addColumn("deviceClassId"); + QTest::addColumn("eventTypeId"); QTest::addColumn("expectedStatusCode"); QTest::addColumn("error"); - QTest::newRow("all ActionTypes") << mockDeviceClassId << EventTypeId() << 200 << DeviceManager::DeviceErrorNoError; - QTest::newRow("EventType 1") << mockDeviceClassId << mockEvent1Id << 200 << DeviceManager::DeviceErrorNoError; - QTest::newRow("EventType 2") << mockDeviceClassId << mockEvent2Id << 200 << DeviceManager::DeviceErrorNoError; - QTest::newRow("invalid DeviceClassId") << DeviceClassId::createDeviceClassId() << mockEvent2Id << 404 << DeviceManager::DeviceErrorDeviceClassNotFound; - QTest::newRow("invalid EventTypeId") << mockDeviceClassId << EventTypeId::createEventTypeId() << 404 << DeviceManager::DeviceErrorEventTypeNotFound; + QTest::newRow("all ActionTypes") << mockDeviceClassId.toString() << QString() << 200 << DeviceManager::DeviceErrorNoError; + QTest::newRow("EventType 1") << mockDeviceClassId.toString() << mockEvent1Id.toString() << 200 << DeviceManager::DeviceErrorNoError; + QTest::newRow("EventType 2") << mockDeviceClassId.toString() << mockEvent2Id.toString() << 200 << DeviceManager::DeviceErrorNoError; + QTest::newRow("invalid DeviceClassId") << DeviceClassId::createDeviceClassId().toString() << mockEvent2Id.toString() << 404 << DeviceManager::DeviceErrorDeviceClassNotFound; + QTest::newRow("invalid EventTypeId") << mockDeviceClassId.toString() << EventTypeId::createEventTypeId().toString() << 404 << DeviceManager::DeviceErrorEventTypeNotFound; + QTest::newRow("invalid EventTypeId format") << mockDeviceClassId.toString() << "uuid" << 400 << DeviceManager::DeviceErrorEventTypeNotFound; + QTest::newRow("invalid DeviceClassId format") << "uuid" << "uuid" << 400 << DeviceManager::DeviceErrorDeviceClassNotFound; } void TestRestDeviceClasses::getEventTypes() { - QFETCH(DeviceClassId, deviceClassId); - QFETCH(EventTypeId, eventTypeId); + QFETCH(QString, deviceClassId); + QFETCH(QString, eventTypeId); QFETCH(int, expectedStatusCode); QFETCH(DeviceManager::DeviceError, error); QNetworkRequest request; if (!eventTypeId.isNull()) { - request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/eventtypes/%2").arg(deviceClassId.toString()).arg(eventTypeId.toString()))); + request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/eventtypes/%2").arg(deviceClassId).arg(eventTypeId))); } else { // Get all actiontypes - request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/eventtypes").arg(deviceClassId.toString()))); + request.setUrl(QUrl(QString("http://localhost:3333/api/v1/deviceclasses/%1/eventtypes").arg(deviceClassId))); } QVariant response = getAndWait(request, expectedStatusCode); @@ -197,15 +215,24 @@ void TestRestDeviceClasses::discoverDevices_data() QTest::addColumn("expectedStatusCode"); QTest::addColumn("error"); - QVariantList discoveryParams; QVariantMap resultCountParam; resultCountParam.insert("name", "resultCount"); resultCountParam.insert("value", 1); + + QVariantMap invalidResultCountParam; + invalidResultCountParam.insert("name", "resultCount"); + invalidResultCountParam.insert("value", 10); + + QVariantList discoveryParams; discoveryParams.append(resultCountParam); + QVariantList invalidDiscoveryParams; + invalidDiscoveryParams.append(invalidResultCountParam); + QTest::newRow("valid deviceClassId without params") << mockDeviceClassId << 2 << QVariantList() << 200 << DeviceManager::DeviceErrorNoError; QTest::newRow("valid deviceClassId with params") << mockDeviceClassId << 1 << discoveryParams << 200 << DeviceManager::DeviceErrorNoError; QTest::newRow("invalid deviceClassId") << DeviceClassId::createDeviceClassId() << 0 << QVariantList() << 404 << DeviceManager::DeviceErrorDeviceClassNotFound; + QTest::newRow("valid deviceClassId with invalid params") << mockDeviceClassId << 10 << invalidDiscoveryParams << 500 << DeviceManager::DeviceErrorInvalidParameter; } void TestRestDeviceClasses::discoverDevices() diff --git a/tests/auto/restrules/testrestrules.cpp b/tests/auto/restrules/testrestrules.cpp index d6fb9d7a..a7077ef8 100644 --- a/tests/auto/restrules/testrestrules.cpp +++ b/tests/auto/restrules/testrestrules.cpp @@ -54,6 +54,7 @@ private: private slots: void getRules(); + void findRule(); void invalidMethod(); void invalidPath(); @@ -209,6 +210,37 @@ void TestRestRules::getRules() } } +void TestRestRules::findRule() +{ + QVariant params = validIntStateBasedRule("Find", true, true); + QNetworkRequest request(QUrl(QString("http://localhost:3333/api/v1/rules"))); + request.setHeader(QNetworkRequest::ContentTypeHeader, "text/json"); + QVariant response = postAndWait(request, params); + + RuleId ruleId = RuleId(response.toMap().value("id").toString()); + QVERIFY(!ruleId.isNull()); + + QUrl url(QString("http://localhost:3333/api/v1/rules/%1").arg(ruleId.toString())); + QUrlQuery query; + query.addQueryItem("deviceId", m_mockDeviceId.toString()); + url.setQuery(query); + request.setUrl(QUrl(url)); + response = getAndWait(request); + QVERIFY(!response.isNull()); + + // REMOVE rule + request.setUrl(QUrl(QString("http://localhost:3333/api/v1/rules/%1").arg(ruleId.toString()))); + response = deleteAndWait(request); + QVERIFY(!response.isNull()); + QCOMPARE(JsonTypes::ruleErrorToString(RuleEngine::RuleErrorNoError), response.toMap().value("error").toString()); + + // check if removed + request.setUrl(QUrl(QString("http://localhost:3333/api/v1/rules/%1").arg(ruleId.toString()))); + response = getAndWait(request, 404); + QVERIFY(!response.isNull()); + +} + void TestRestRules::invalidMethod() { QNetworkAccessManager nam;