mirror of https://github.com/nymea/nymea.git
2260 lines
94 KiB
C++
2260 lines
94 KiB
C++
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* *
|
|
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
|
|
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
|
|
* *
|
|
* This file is part of nymea. *
|
|
* *
|
|
* nymea is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation, version 2 of the License. *
|
|
* *
|
|
**
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with nymea. If not, see <http://www.gnu.org/licenses/>. *
|
|
* *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
#include "nymeatestbase.h"
|
|
#include "nymeacore.h"
|
|
#include "servers/mocktcpserver.h"
|
|
|
|
#include "platform/platform.h"
|
|
#include "platform/platformsystemcontroller.h"
|
|
|
|
using namespace nymeaserver;
|
|
|
|
class TestTimeManager: public NymeaTestBase
|
|
{
|
|
Q_OBJECT
|
|
|
|
private:
|
|
inline void verifyRuleError(const QVariant &response, RuleEngine::RuleError error = RuleEngine::RuleErrorNoError) {
|
|
verifyError(response, "ruleError", enumValueName(error));
|
|
}
|
|
|
|
private slots:
|
|
void initTestCase();
|
|
|
|
void loadSaveTimeDescriptor_data();
|
|
void loadSaveTimeDescriptor();
|
|
|
|
void addTimeDescriptor_data();
|
|
void addTimeDescriptor();
|
|
|
|
void addTimeDescriptorInvalidTimes_data();
|
|
void addTimeDescriptorInvalidTimes();
|
|
|
|
// CalendarItems
|
|
void testCalendarDateTime_data();
|
|
void testCalendarDateTime();
|
|
|
|
void testCalendarItemHourly_data();
|
|
void testCalendarItemHourly();
|
|
|
|
void testCalendarItemDaily_data();
|
|
void testCalendarItemDaily();
|
|
|
|
void testCalendarItemWeekly_data();
|
|
void testCalendarItemWeekly();
|
|
|
|
void testCalendarItemMonthly_data();
|
|
void testCalendarItemMonthly();
|
|
|
|
void testCalendarYearlyDateTime_data();
|
|
void testCalendarYearlyDateTime();
|
|
|
|
void testCalendarItemStates_data();
|
|
void testCalendarItemStates();
|
|
|
|
void testCalendarItemEvent_data();
|
|
void testCalendarItemEvent();
|
|
|
|
void testCalendarItemStatesEvent_data();
|
|
void testCalendarItemStatesEvent();
|
|
|
|
void testCalendarItemCrossesMidnight();
|
|
|
|
void testEventBasedWithCalendarItemCrossingMidnight();
|
|
|
|
// TimeEventItems
|
|
void testEventItemDateTime_data();
|
|
void testEventItemDateTime();
|
|
|
|
void testEventItemHourly_data();
|
|
void testEventItemHourly();
|
|
|
|
void testEventItemDaily_data();
|
|
void testEventItemDaily();
|
|
|
|
void testEventItemWeekly_data();
|
|
void testEventItemWeekly();
|
|
|
|
void testEventItemMonthly_data();
|
|
void testEventItemMonthly();
|
|
|
|
void testEventItemYearly_data();
|
|
void testEventItemYearly();
|
|
|
|
void testEventItemStates_data();
|
|
void testEventItemStates();
|
|
|
|
void testEnableDisableTimeRule();
|
|
|
|
private:
|
|
void initTimeManager();
|
|
|
|
void verifyRuleExecuted(const ActionTypeId &actionTypeId);
|
|
void verifyRuleNotExecuted();
|
|
|
|
void cleanupMockHistory();
|
|
|
|
void removeAllRules();
|
|
|
|
void setIntState(const int &value);
|
|
void setBoolState(const bool &value);
|
|
void triggerMockEvent1();
|
|
|
|
QVariantMap createTimeEventItem(const QString &time = QString(), const QVariantMap &repeatingOption = QVariantMap()) const;
|
|
QVariantMap createTimeEventItem(const int &dateTime, const QVariantMap &repeatingOption = QVariantMap()) const;
|
|
QVariantMap createTimeDescriptorTimeEvent(const QVariantMap &timeEventItem) const;
|
|
QVariantMap createTimeDescriptorTimeEvent(const QVariantList &timeEventItems) const;
|
|
|
|
QVariantMap createCalendarItem(const QString &time = QString(), const uint &duration = 0, const QVariantMap &repeatingOption = QVariantMap()) const;
|
|
QVariantMap createCalendarItem(const int &dateTime, const uint &duration = 0, const QVariantMap &repeatingOption = QVariantMap()) const;
|
|
QVariantMap createTimeDescriptorCalendar(const QVariantMap &calendarItem) const;
|
|
QVariantMap createTimeDescriptorCalendar(const QVariantList &calendarItems) const;
|
|
};
|
|
|
|
void TestTimeManager::initTestCase()
|
|
{
|
|
NymeaTestBase::initTestCase();
|
|
QLoggingCategory::setFilterRules("*.debug=false\n"
|
|
"Tests.debug=true\n"
|
|
"RuleEngine.debug=true\n"
|
|
// "RuleEngineDebug.debug=true\n"
|
|
"MockDevice.debug=true\n"
|
|
"JsonRpc.debug=true\n"
|
|
"TimeManager.debug=true");
|
|
}
|
|
|
|
void TestTimeManager::loadSaveTimeDescriptor_data()
|
|
{
|
|
// Repeating options
|
|
QVariantMap repeatingOptionWeekly;
|
|
repeatingOptionWeekly.insert("mode", "RepeatingModeWeekly");
|
|
repeatingOptionWeekly.insert("weekDays", QVariantList() << 2 << 4 << 5);
|
|
|
|
QVariantMap repeatingOptionMonthly;
|
|
repeatingOptionMonthly.insert("mode", "RepeatingModeMonthly");
|
|
repeatingOptionMonthly.insert("monthDays", QVariantList() << 20 << 14 << 5);
|
|
|
|
QVariantMap repeatingOptionYearly;
|
|
repeatingOptionYearly.insert("mode", "RepeatingModeYearly");
|
|
|
|
QVariantList calendarItems;
|
|
calendarItems.append(createCalendarItem("12:10", 20, repeatingOptionWeekly));
|
|
calendarItems.append(createCalendarItem("23:33", 11, repeatingOptionMonthly));
|
|
calendarItems.append(createCalendarItem(QDateTime::currentDateTime().toTime_t(), 50, repeatingOptionYearly));
|
|
|
|
QVariantList timeEventItems;
|
|
timeEventItems.append(createTimeEventItem(QDateTime::currentDateTime().toTime_t(), repeatingOptionYearly));
|
|
timeEventItems.append(createTimeEventItem("13:12", repeatingOptionWeekly));
|
|
timeEventItems.append(createTimeEventItem("18:45", repeatingOptionMonthly));
|
|
|
|
QTest::addColumn<QVariantMap>("timeDescriptor");
|
|
|
|
QTest::newRow("calendarItems") << createTimeDescriptorCalendar(calendarItems);
|
|
// QTest::newRow("timeEventItems") << createTimeDescriptorTimeEvent(timeEventItems);
|
|
}
|
|
|
|
void TestTimeManager::loadSaveTimeDescriptor()
|
|
{
|
|
QFETCH(QVariantMap, timeDescriptor);
|
|
|
|
initTimeManager();
|
|
|
|
// Action (without params)
|
|
QVariantMap ruleMap; QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
// Create the rule map
|
|
ruleMap.insert("name", "Time based weekly calendar rule");
|
|
ruleMap.insert("timeDescriptor", timeDescriptor);
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
|
|
// Add the rule
|
|
qCDebug(dcTests()) << "Adding rule:" << qUtf8Printable(QJsonDocument::fromVariant(ruleMap).toJson());
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QVariantMap params;
|
|
params.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
verifyRuleError(response);
|
|
|
|
QVariantMap timeDescriptorMap = response.toMap().value("params").toMap().value("rule").toMap().value("timeDescriptor").toMap();
|
|
|
|
QVERIFY2(timeDescriptorMap == timeDescriptor,
|
|
QString("TimeDescriptor not matching:\nExpected: %1\nGot: %2")
|
|
.arg(QString(QJsonDocument::fromVariant(timeDescriptor).toJson()))
|
|
.arg(QString(QJsonDocument::fromVariant(timeDescriptorMap).toJson()))
|
|
.toUtf8());
|
|
|
|
// Restart the server
|
|
restartServer();
|
|
|
|
// Get the loaded rule
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
verifyRuleError(response);
|
|
|
|
QVariantMap timeDescriptorMapLoaded = response.toMap().value("params").toMap().value("rule").toMap().value("timeDescriptor").toMap();
|
|
|
|
QVERIFY2(timeDescriptorMap == timeDescriptorMapLoaded,
|
|
QString("TimeDescriptor not matching:\nExpected: %1\nGot: %2")
|
|
.arg(QString(QJsonDocument::fromVariant(timeDescriptorMap).toJson()))
|
|
.arg(QString(QJsonDocument::fromVariant(timeDescriptorMapLoaded).toJson()))
|
|
.toUtf8());
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::addTimeDescriptor_data()
|
|
{
|
|
// valid RepeatingOptions
|
|
QVariantMap repeatingOptionDaily;
|
|
repeatingOptionDaily.insert("mode", "RepeatingModeDaily");
|
|
|
|
QVariantMap repeatingOptionNone;
|
|
repeatingOptionNone.insert("mode", "RepeatingModeNone");
|
|
|
|
QVariantMap repeatingOptionHourly;
|
|
repeatingOptionHourly.insert("mode", "RepeatingModeHourly");
|
|
|
|
QVariantMap repeatingOptionWeeklyMultiple;
|
|
repeatingOptionWeeklyMultiple.insert("mode", "RepeatingModeWeekly");
|
|
repeatingOptionWeeklyMultiple.insert("weekDays", QVariantList() << 2 << 4 << 5);
|
|
|
|
QVariantMap repeatingOptionMonthlyMultiple;
|
|
repeatingOptionMonthlyMultiple.insert("mode", "RepeatingModeMonthly");
|
|
repeatingOptionMonthlyMultiple.insert("monthDays", QVariantList() << 20 << 14 << 5);
|
|
|
|
QVariantMap repeatingOptionYearly;
|
|
repeatingOptionYearly.insert("mode", "RepeatingModeYearly");
|
|
|
|
// invalid RepeatingOptions
|
|
QVariantMap repeatingOptionInvalidNone;
|
|
repeatingOptionInvalidNone.insert("mode", "RepeatingModeNone");
|
|
repeatingOptionInvalidNone.insert("monthDays", QVariantList() << 13 << 12 << 27);
|
|
|
|
QVariantMap repeatingOptionInvalidWeekly;
|
|
repeatingOptionInvalidWeekly.insert("mode", "RepeatingModeWeekly");
|
|
repeatingOptionInvalidWeekly.insert("monthDays", QVariantList() << 12 << 2 << 7);
|
|
|
|
QVariantMap repeatingOptionInvalidMonthly;
|
|
repeatingOptionInvalidMonthly.insert("mode", "RepeatingModeMonthly");
|
|
repeatingOptionInvalidMonthly.insert("weekDays", QVariantList() << 1 << 2 << 7);
|
|
|
|
QVariantMap repeatingOptionInvalidWeekDays;
|
|
repeatingOptionInvalidWeekDays.insert("mode", "RepeatingModeWeekly");
|
|
repeatingOptionInvalidWeekDays.insert("weekDays", QVariantList() << -1);
|
|
|
|
QVariantMap repeatingOptionInvalidWeekDays2;
|
|
repeatingOptionInvalidWeekDays2.insert("mode", "RepeatingModeWeekly");
|
|
repeatingOptionInvalidWeekDays2.insert("weekDays", QVariantList() << 8);
|
|
|
|
QVariantMap repeatingOptionInvalidMonthDays;
|
|
repeatingOptionInvalidMonthDays.insert("mode", "RepeatingModeMonthly");
|
|
repeatingOptionInvalidMonthDays.insert("monthDays", QVariantList() << -1);
|
|
|
|
QVariantMap repeatingOptionInvalidMonthDays2;
|
|
repeatingOptionInvalidMonthDays2.insert("mode", "RepeatingModeMonthly");
|
|
repeatingOptionInvalidMonthDays2.insert("monthDays", QVariantList() << 32);
|
|
|
|
// Multiple calendar items
|
|
QVariantList calendarItems;
|
|
calendarItems.append(createCalendarItem("08:00", 5, repeatingOptionDaily));
|
|
calendarItems.append(createCalendarItem("09:00", 5, repeatingOptionWeeklyMultiple));
|
|
|
|
// Multiple timeEvent items
|
|
QVariantList timeEventItems;
|
|
timeEventItems.append(createTimeEventItem("08:00", repeatingOptionDaily));
|
|
timeEventItems.append(createTimeEventItem("09:00", repeatingOptionWeeklyMultiple));
|
|
|
|
QTest::addColumn<QVariantMap>("timeDescriptor");
|
|
QTest::addColumn<RuleEngine::RuleError>("error");
|
|
|
|
QTest::newRow("valid: calendarItem") << createTimeDescriptorCalendar(createCalendarItem("08:00", 5)) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: calendarItem dateTime") << createTimeDescriptorCalendar(createCalendarItem(QDateTime::currentDateTime().toTime_t(), 5)) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: calendarItem dateTime - yearly") << createTimeDescriptorCalendar(createCalendarItem(QDateTime::currentDateTime().toTime_t(), 5, repeatingOptionYearly)) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: calendarItem - daily") << createTimeDescriptorCalendar(createCalendarItem("08:00", 5, repeatingOptionDaily)) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: calendarItem - none") << createTimeDescriptorCalendar(createCalendarItem("09:00", 30, repeatingOptionNone)) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: calendarItem - hourly") << createTimeDescriptorCalendar(createCalendarItem("09:00", 30, repeatingOptionHourly)) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: calendarItems - weekly - multiple days") << createTimeDescriptorCalendar(calendarItems) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: calendarItem - monthly - multiple days") << createTimeDescriptorCalendar(createCalendarItem("23:00", 5, repeatingOptionMonthlyMultiple)) << RuleEngine::RuleErrorNoError;
|
|
|
|
QTest::newRow("valid: timeEventItem") << createTimeDescriptorTimeEvent(createTimeEventItem("08:00")) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: timeEventItem dateTime") << createTimeDescriptorTimeEvent(createTimeEventItem(QDateTime::currentDateTime().toTime_t())) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: timeEventItem dateTime - yearly") << createTimeDescriptorTimeEvent(createTimeEventItem(QDateTime::currentDateTime().toTime_t(), repeatingOptionYearly)) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: timeEventItem - daily") << createTimeDescriptorTimeEvent(createTimeEventItem("08:00", repeatingOptionDaily)) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: timeEventItem - none") << createTimeDescriptorTimeEvent(createTimeEventItem("09:00", repeatingOptionNone)) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: timeEventItem - hourly") << createTimeDescriptorTimeEvent(createTimeEventItem("09:00", repeatingOptionHourly)) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: timeEventItem - weekly - multiple days") << createTimeDescriptorTimeEvent(timeEventItems) << RuleEngine::RuleErrorNoError;
|
|
QTest::newRow("valid: timeEventItem - monthly - multiple days") << createTimeDescriptorTimeEvent(createTimeEventItem("23:00", repeatingOptionMonthlyMultiple)) << RuleEngine::RuleErrorNoError;
|
|
|
|
QTest::newRow("invalid: calendarItem none") << createTimeDescriptorCalendar(createCalendarItem("00:12", 12, repeatingOptionInvalidNone)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: calendarItem dateTime - daily") << createTimeDescriptorCalendar(createCalendarItem(QDateTime::currentDateTime().toTime_t(), 5, repeatingOptionDaily)) << RuleEngine::RuleErrorInvalidCalendarItem;
|
|
QTest::newRow("invalid: calendarItem invalid duration") << createTimeDescriptorCalendar(createCalendarItem("12:00", 0)) << RuleEngine::RuleErrorInvalidCalendarItem;
|
|
QTest::newRow("invalid: calendarItem - monthly - weekDays") << createTimeDescriptorCalendar(createCalendarItem("13:13", 5, repeatingOptionInvalidMonthly)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: calendarItem - weekly - monthDays") << createTimeDescriptorCalendar(createCalendarItem("15:30", 20, repeatingOptionInvalidWeekly)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: calendarItem - invalid weekdays (negative)") << createTimeDescriptorCalendar(createCalendarItem("13:13", 5, repeatingOptionInvalidWeekDays)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: calendarItem - invalid weekdays (to big)") << createTimeDescriptorCalendar(createCalendarItem("13:13", 5, repeatingOptionInvalidWeekDays2)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: calendarItem - invalid monthdays (negative)") << createTimeDescriptorCalendar(createCalendarItem("13:13", 5, repeatingOptionInvalidMonthDays)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: calendarItem - invalid monthdays (to big)") << createTimeDescriptorCalendar(createCalendarItem("13:13", 5, repeatingOptionInvalidMonthDays2)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
|
|
QTest::newRow("invalid: timeEventItem none") << createTimeDescriptorTimeEvent(createTimeEventItem("00:12", repeatingOptionInvalidNone)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: timeEventItem - dateTime + repeatingOption") << createTimeDescriptorTimeEvent(createTimeEventItem(QDateTime::currentDateTime().toTime_t(), repeatingOptionDaily)) << RuleEngine::RuleErrorInvalidTimeEventItem;
|
|
QTest::newRow("invalid: timeEventItem - monthly - weekDays") << createTimeDescriptorTimeEvent(createTimeEventItem("13:13", repeatingOptionInvalidMonthly)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: timeEventItem - weekly - monthDays") << createTimeDescriptorTimeEvent(createTimeEventItem("15:30", repeatingOptionInvalidWeekly)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: timeEventItem - invalid weekdays (negative)") << createTimeDescriptorTimeEvent(createTimeEventItem("13:13", repeatingOptionInvalidWeekDays)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: timeEventItem - invalid weekdays (to big)") << createTimeDescriptorTimeEvent(createTimeEventItem("13:13", repeatingOptionInvalidWeekDays2)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: timeEventItem - invalid monthdays (negative)") << createTimeDescriptorTimeEvent(createTimeEventItem("13:13", repeatingOptionInvalidMonthDays)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
QTest::newRow("invalid: timeEventItem - invalid monthdays (to big)") << createTimeDescriptorTimeEvent(createTimeEventItem("13:13", repeatingOptionInvalidMonthDays2)) << RuleEngine::RuleErrorInvalidRepeatingOption;
|
|
}
|
|
|
|
void TestTimeManager::addTimeDescriptor()
|
|
{
|
|
QFETCH(QVariantMap, timeDescriptor);
|
|
QFETCH(RuleEngine::RuleError, error);
|
|
|
|
// ADD the rule
|
|
QVariantMap ruleMap; QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
ruleMap.insert("name", "TimeBased rule");
|
|
ruleMap.insert("timeDescriptor", timeDescriptor);
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response, error);
|
|
if (error != RuleEngine::RuleErrorNoError)
|
|
return;
|
|
|
|
RuleId newRuleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", newRuleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::addTimeDescriptorInvalidTimes_data()
|
|
{
|
|
QTest::addColumn<QVariantMap>("timeDescriptor");
|
|
|
|
QTest::newRow("invalid: calendarItem empty") << createTimeDescriptorCalendar(createCalendarItem());
|
|
QTest::newRow("invalid: calendarItem invalid time") << createTimeDescriptorCalendar(createCalendarItem("35:80", 5));
|
|
|
|
QTest::newRow("invalid: timeEventItem empty") << createTimeDescriptorTimeEvent(createTimeEventItem());
|
|
QTest::newRow("invalid: timeEventItem invalid time") << createTimeDescriptorTimeEvent(createTimeEventItem("35:80"));
|
|
}
|
|
|
|
void TestTimeManager::addTimeDescriptorInvalidTimes()
|
|
{
|
|
QFETCH(QVariantMap, timeDescriptor);
|
|
|
|
// ADD the rule
|
|
QVariantMap ruleMap; QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
ruleMap.insert("name", "TimeBased rule");
|
|
ruleMap.insert("timeDescriptor", timeDescriptor);
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
QVERIFY2(response.toMap().value("status").toString() == "error", "Invalid time must fail JSON verification.");
|
|
}
|
|
|
|
void TestTimeManager::testCalendarDateTime_data()
|
|
{
|
|
QTest::addColumn<QDateTime>("dateTime");
|
|
QTest::addColumn<int>("duration");
|
|
|
|
QTest::newRow("dateTime - christmas") << QDateTime::fromString("24.12.2017 20:00", "dd.MM.yyyy hh:mm") << 60;
|
|
QTest::newRow("dateTime - new year") << QDateTime::fromString("31.12.2017 23:00", "dd.MM.yyyy hh:mm") << 120;
|
|
QTest::newRow("dateTime - valentines day") << QDateTime::fromString("14.02.2017 08:00", "dd.MM.yyyy hh:mm") << 120;
|
|
}
|
|
|
|
void TestTimeManager::testCalendarDateTime()
|
|
{
|
|
QFETCH(QDateTime, dateTime);
|
|
QFETCH(int, duration);
|
|
|
|
initTimeManager();
|
|
|
|
// Action (without params)
|
|
QVariantMap ruleMap; QVariantMap action; QVariantMap exitAction;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
// Exit action (with params)
|
|
QVariantList actionParams;
|
|
QVariantMap param1;
|
|
param1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId);
|
|
param1.insert("value", 12);
|
|
actionParams.append(param1);
|
|
QVariantMap param2;
|
|
param2.insert("paramTypeId", mockWithParamsActionParam2ParamTypeId);
|
|
param2.insert("value", true);
|
|
actionParams.append(param2);
|
|
exitAction.insert("actionTypeId", mockWithParamsActionTypeId);
|
|
exitAction.insert("deviceId", m_mockDeviceId);
|
|
exitAction.insert("ruleActionParams", actionParams);
|
|
|
|
// CalendarItem
|
|
QVariantMap calendarItem;
|
|
calendarItem.insert("datetime", QVariant(dateTime.toTime_t()));
|
|
calendarItem.insert("duration", QVariant(duration));
|
|
|
|
// Create the rule map
|
|
ruleMap.insert("name", "Time based hourly calendar rule");
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorCalendar(calendarItem));
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("exitActions", QVariantList() << exitAction);
|
|
|
|
// Add the rule
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QDateTime oneMinuteBeforeEvent = dateTime.addSecs(-60);
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(oneMinuteBeforeEvent);
|
|
verifyRuleNotExecuted();
|
|
// active
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// active unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(duration * 30));
|
|
verifyRuleNotExecuted();
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(duration * 60));
|
|
verifyRuleExecuted(mockWithParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// inactive unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs((duration + 1) * 60));
|
|
verifyRuleNotExecuted();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemHourly_data()
|
|
{
|
|
QTest::addColumn<int>("duration");
|
|
|
|
//QTest::newRow("hourly - for 60 minutes") << 60;
|
|
QTest::newRow("hourly - for 5 minutes") << 5;
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemHourly()
|
|
{
|
|
QFETCH(int, duration);
|
|
|
|
initTimeManager();
|
|
|
|
QVariantMap ruleMap; QVariantMap action; QVariantMap exitAction; QVariantMap repeatingOptionHourly;
|
|
repeatingOptionHourly.insert("mode", "RepeatingModeHourly");
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
exitAction.insert("actionTypeId", mockWithParamsActionTypeId);
|
|
QVariantList actionParams;
|
|
QVariantMap param1;
|
|
param1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId);
|
|
param1.insert("value", 7);
|
|
actionParams.append(param1);
|
|
QVariantMap param2;
|
|
param2.insert("paramTypeId", mockWithParamsActionParam2ParamTypeId);
|
|
param2.insert("value", true);
|
|
actionParams.append(param2);
|
|
exitAction.insert("deviceId", m_mockDeviceId);
|
|
exitAction.insert("ruleActionParams", actionParams);
|
|
ruleMap.insert("name", "Time based hourly calendar rule");
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorCalendar(createCalendarItem("08:05", duration, repeatingOptionHourly)));
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("exitActions", QVariantList() << exitAction);
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QVariantMap params;
|
|
params.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
|
|
QDateTime currentDateTime = NymeaCore::instance()->timeManager()->currentDateTime();
|
|
|
|
QDateTime future = QDateTime(currentDateTime.date(), QTime(8, 4));
|
|
|
|
// Check if should be enabled always
|
|
if (duration == 60) {
|
|
NymeaCore::instance()->timeManager()->setTime(future);
|
|
// Should be active since adding
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
} else {
|
|
// check the next 24 hours in 8h steps
|
|
for (int i = 0; i < 24; i+=8) {
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(future);
|
|
verifyRuleNotExecuted();
|
|
// active
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(currentDateTime.date(), QTime(future.time().hour(), 5)));
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// active unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(currentDateTime.date(), QTime(future.time().hour(), 7)));
|
|
verifyRuleNotExecuted();
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(currentDateTime.date(), QTime(future.time().hour(), 10)));
|
|
verifyRuleExecuted(mockWithParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// inactive unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(currentDateTime.date(), QTime(future.time().hour(), 11)));
|
|
verifyRuleNotExecuted();
|
|
|
|
// 'i' hours "Back to the future"
|
|
future = future.addSecs(i*60*60);
|
|
}
|
|
}
|
|
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemDaily_data()
|
|
{
|
|
QVariantMap repeatingOptionDaily;
|
|
repeatingOptionDaily.insert("mode", "RepeatingModeDaily");
|
|
|
|
QTest::addColumn<QVariantMap>("timeDescriptor");
|
|
QTest::addColumn<QString>("time");
|
|
QTest::addColumn<int>("duration");
|
|
|
|
QTest::newRow("daily") << createTimeDescriptorCalendar(createCalendarItem("06:55", 10, repeatingOptionDaily)) << "06:55" << 10;
|
|
QTest::newRow("daily - jump date") << createTimeDescriptorCalendar(createCalendarItem("23:55", 10, repeatingOptionDaily)) << "23:55" << 10;
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemDaily()
|
|
{
|
|
QFETCH(QVariantMap, timeDescriptor);
|
|
QFETCH(QString, time);
|
|
|
|
initTimeManager();
|
|
|
|
QVariantMap ruleMap; QVariantMap action; QVariantMap exitAction;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
exitAction.insert("actionTypeId", mockWithParamsActionTypeId);
|
|
QVariantList actionParams;
|
|
QVariantMap param1;
|
|
param1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId);
|
|
param1.insert("value", 12);
|
|
actionParams.append(param1);
|
|
QVariantMap param2;
|
|
param2.insert("paramTypeId", mockWithParamsActionParam2ParamTypeId);
|
|
param2.insert("value", true);
|
|
actionParams.append(param2);
|
|
exitAction.insert("deviceId", m_mockDeviceId);
|
|
exitAction.insert("ruleActionParams", actionParams);
|
|
ruleMap.insert("name", "Time based hourly calendar rule");
|
|
ruleMap.insert("timeDescriptor", timeDescriptor);
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("exitActions", QVariantList() << exitAction);
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QDateTime currentDateTime = NymeaCore::instance()->timeManager()->currentDateTime();
|
|
|
|
// start with one minute before starttime today
|
|
QDateTime future = QDateTime(currentDateTime.date(), QTime::fromString(time, "hh:mm").addSecs(-60));
|
|
|
|
// if always true
|
|
if (time == "08:00") {
|
|
NymeaCore::instance()->timeManager()->setTime(future);
|
|
// Should be active since adding
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
} else {
|
|
// check the next 7 days
|
|
for (int i = 0; i < 7; i++) {
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(future);
|
|
verifyRuleNotExecuted();
|
|
// active
|
|
NymeaCore::instance()->timeManager()->setTime(future.addSecs(60));
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// active unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(future.addSecs(6* 60));
|
|
verifyRuleNotExecuted();
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(future.addSecs(11 * 60));
|
|
verifyRuleExecuted(mockWithParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// inactive unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(future.addSecs(12 * 60));
|
|
verifyRuleNotExecuted();
|
|
// One day "Back to the future"
|
|
future = future.addDays(1);
|
|
}
|
|
}
|
|
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemWeekly_data()
|
|
{
|
|
QVariantMap repeatingOptionWeekly;
|
|
repeatingOptionWeekly.insert("mode", "RepeatingModeWeekly");
|
|
repeatingOptionWeekly.insert("weekDays", QVariantList() << 2 << 4 << 6);
|
|
|
|
QVariantMap repeatingOptionWeeklyOverlapping;
|
|
repeatingOptionWeeklyOverlapping.insert("mode", "RepeatingModeWeekly");
|
|
repeatingOptionWeeklyOverlapping.insert("weekDays", QVariantList() << 6);
|
|
|
|
QTest::addColumn<QVariantMap>("timeDescriptor");
|
|
QTest::addColumn<QVariantMap>("repeatingOption");
|
|
QTest::addColumn<QString>("time");
|
|
QTest::addColumn<bool>("overlapping");
|
|
|
|
QTest::newRow("weekly") << createTimeDescriptorCalendar(createCalendarItem("06:55", 10, repeatingOptionWeekly)) << repeatingOptionWeekly << "06:55" << false;
|
|
//QTest::newRow("weekly - always") << createTimeDescriptorCalendar(createCalendarItem("22:34", 10080)) << QVariantMap() << "22:34" << false;
|
|
//QTest::newRow("weekly - overlapping") << createTimeDescriptorCalendar(createCalendarItem("08:00", 2880, repeatingOptionWeeklyOverlapping)) << repeatingOptionWeeklyOverlapping << "08:00" << true;
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemWeekly()
|
|
{
|
|
QFETCH(QVariantMap, timeDescriptor);
|
|
QFETCH(QVariantMap, repeatingOption);
|
|
QFETCH(QString, time);
|
|
QFETCH(bool, overlapping);
|
|
|
|
initTimeManager();
|
|
|
|
// Action (without params)
|
|
QVariantMap ruleMap; QVariantMap action; QVariantMap exitAction;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
// Exit action (with params)
|
|
QVariantList actionParams;
|
|
QVariantMap param1;
|
|
param1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId);
|
|
param1.insert("value", 12);
|
|
actionParams.append(param1);
|
|
QVariantMap param2;
|
|
param2.insert("paramTypeId", mockWithParamsActionParam2ParamTypeId);
|
|
param2.insert("value", true);
|
|
actionParams.append(param2);
|
|
exitAction.insert("actionTypeId", mockWithParamsActionTypeId);
|
|
exitAction.insert("deviceId", m_mockDeviceId);
|
|
exitAction.insert("ruleActionParams", actionParams);
|
|
|
|
// Create the rule map
|
|
ruleMap.insert("name", "Time based weekly calendar rule");
|
|
ruleMap.insert("timeDescriptor", timeDescriptor);
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("exitActions", QVariantList() << exitAction);
|
|
|
|
// Add the rule
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QDateTime currentDateTime = NymeaCore::instance()->timeManager()->currentDateTime();
|
|
|
|
// start with one minute before starttime today
|
|
QDateTime future = QDateTime(currentDateTime.date(), QTime::fromString(time, "hh:mm").addSecs(-60));
|
|
QVariantList weekDaysVariant = repeatingOption.value("weekDays").toList();
|
|
|
|
QList<int> weekDays;
|
|
foreach (const QVariant &variant, weekDaysVariant) {
|
|
weekDays.append(variant.toInt());
|
|
}
|
|
|
|
// the whole week active (always)
|
|
if (repeatingOption.isEmpty()) {
|
|
NymeaCore::instance()->timeManager()->setTime(future);
|
|
// Should be active since adding
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
} else {
|
|
if (!overlapping) {
|
|
// check the next 7 days (because not overlapping the week)
|
|
for (int i = 0; i < 7; i++) {
|
|
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(future);
|
|
verifyRuleNotExecuted();
|
|
|
|
// Check if today is a weekday
|
|
if (weekDays.contains(future.date().dayOfWeek())) {
|
|
// should trigger today
|
|
// active
|
|
NymeaCore::instance()->timeManager()->setTime(future.addSecs(60));
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// active unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(future.addSecs(6* 60));
|
|
verifyRuleNotExecuted();
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(future.addSecs(11 * 60));
|
|
verifyRuleExecuted(mockWithParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// inactive unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(future.addSecs(12 * 60));
|
|
verifyRuleNotExecuted();
|
|
|
|
// One day "Back to the future"
|
|
future = future.addDays(1);
|
|
} else {
|
|
// should not trigger today
|
|
NymeaCore::instance()->timeManager()->setTime(future.addSecs(6* 60));
|
|
verifyRuleNotExecuted();
|
|
|
|
// One day "Back to the future"
|
|
future = future.addDays(1);
|
|
}
|
|
}
|
|
} else {
|
|
// Overlapping the week
|
|
int weekDay = weekDays.first();
|
|
|
|
// go to the next start day (weeksaturday)
|
|
QDateTime startDate = future;
|
|
while (startDate.date().dayOfWeek() < weekDay) {
|
|
startDate = startDate.addDays(1);
|
|
}
|
|
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(startDate);
|
|
verifyRuleNotExecuted();
|
|
|
|
// active
|
|
NymeaCore::instance()->timeManager()->setTime(startDate.addSecs(60));
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
|
|
// still active
|
|
NymeaCore::instance()->timeManager()->setTime(startDate.addDays(1));
|
|
verifyRuleNotExecuted();
|
|
|
|
// still active
|
|
NymeaCore::instance()->timeManager()->setTime(startDate.addDays(2));
|
|
verifyRuleNotExecuted();
|
|
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(startDate.addDays(2).addSecs(60));
|
|
verifyRuleExecuted(mockWithParamsActionTypeId);
|
|
}
|
|
}
|
|
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemMonthly_data()
|
|
{
|
|
QVariantMap repeatingOptionMonthly;
|
|
repeatingOptionMonthly.insert("mode", "RepeatingModeMonthly");
|
|
repeatingOptionMonthly.insert("monthDays", QVariantList() << 1 << 10 << 16 << 20 << 25);
|
|
|
|
QVariantMap repeatingOptionMonthlyOverlapping;
|
|
repeatingOptionMonthlyOverlapping.insert("mode", "RepeatingModeMonthly");
|
|
repeatingOptionMonthlyOverlapping.insert("monthDays", QVariantList() << 28);
|
|
|
|
QTest::addColumn<QVariantMap>("timeDescriptor");
|
|
QTest::addColumn<QVariantMap>("repeatingOption");
|
|
QTest::addColumn<QString>("time");
|
|
QTest::addColumn<bool>("overlapping");
|
|
|
|
QTest::newRow("monthly") << createTimeDescriptorCalendar(createCalendarItem("06:55", 10, repeatingOptionMonthly)) << repeatingOptionMonthly << "06:55" << false;
|
|
//QTest::newRow("monthly - overlapping") << createTimeDescriptorCalendar(createCalendarItem("08:00", 4320, repeatingOptionMonthlyOverlapping)) << repeatingOptionMonthlyOverlapping << "08:00" << true;
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemMonthly()
|
|
{
|
|
QFETCH(QVariantMap, timeDescriptor);
|
|
QFETCH(QVariantMap, repeatingOption);
|
|
QFETCH(QString, time);
|
|
QFETCH(bool, overlapping);
|
|
|
|
initTimeManager();
|
|
|
|
// Action (without params)
|
|
QVariantMap ruleMap; QVariantMap action; QVariantMap exitAction;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
// Exit action (with params)
|
|
QVariantList actionParams;
|
|
QVariantMap param1;
|
|
param1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId);
|
|
param1.insert("value", 12);
|
|
actionParams.append(param1);
|
|
QVariantMap param2;
|
|
param2.insert("paramTypeId", mockWithParamsActionParam2ParamTypeId);
|
|
param2.insert("value", true);
|
|
actionParams.append(param2);
|
|
exitAction.insert("actionTypeId", mockWithParamsActionTypeId);
|
|
exitAction.insert("deviceId", m_mockDeviceId);
|
|
exitAction.insert("ruleActionParams", actionParams);
|
|
|
|
// Create the rule map
|
|
ruleMap.insert("name", "Time based monthly calendar rule");
|
|
ruleMap.insert("timeDescriptor", timeDescriptor);
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("exitActions", QVariantList() << exitAction);
|
|
|
|
// Add the rule
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QDateTime currentDateTime = NymeaCore::instance()->timeManager()->currentDateTime();
|
|
|
|
QVariantList monthDaysVariant = repeatingOption.value("monthDays").toList();
|
|
QList<int> monthDays;
|
|
foreach (const QVariant &variant, monthDaysVariant) {
|
|
monthDays.append(variant.toInt());
|
|
}
|
|
|
|
// start with one minute before starttime today
|
|
QDateTime future = QDateTime(currentDateTime.date(), QTime::fromString(time, "hh:mm").addSecs(-60));
|
|
|
|
if (!overlapping) {
|
|
|
|
// run one month to the future
|
|
for (int i = 0; i < 31; i++) {
|
|
QDateTime dateTime = future.addDays(i);
|
|
// Check if today is a weekday
|
|
if (monthDays.contains(dateTime.date().day())) {
|
|
// should trigger today
|
|
// not active yet
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
verifyRuleNotExecuted();
|
|
// active
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(60));
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// active unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(6* 60));
|
|
verifyRuleNotExecuted();
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(11 * 60));
|
|
verifyRuleExecuted(mockWithParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// inactive unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(12 * 60));
|
|
verifyRuleNotExecuted();
|
|
} else {
|
|
// should not trigger today
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(60));
|
|
verifyRuleNotExecuted();
|
|
}
|
|
}
|
|
} else {
|
|
// Overlapping the month
|
|
int monthDay = monthDays.first();
|
|
QCOMPARE(monthDay, 28);
|
|
|
|
// go to the next start day (28.MM.yyyy)
|
|
QDateTime startDate = future;
|
|
while (startDate.date().day() < monthDay) {
|
|
startDate = startDate.addDays(1);
|
|
}
|
|
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(startDate);
|
|
verifyRuleNotExecuted();
|
|
|
|
// active
|
|
NymeaCore::instance()->timeManager()->setTime(startDate.addSecs(60));
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
|
|
// still active
|
|
NymeaCore::instance()->timeManager()->setTime(startDate.addDays(3));
|
|
verifyRuleNotExecuted();
|
|
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(startDate.addDays(3).addSecs(60));
|
|
verifyRuleExecuted(mockWithParamsActionTypeId);
|
|
}
|
|
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::testCalendarYearlyDateTime_data()
|
|
{
|
|
QTest::addColumn<QDateTime>("dateTime");
|
|
QTest::addColumn<int>("duration");
|
|
|
|
QTest::newRow("dateTime - yearly - christmas") << QDateTime::fromString(QString("24.12.%1 20:00").arg(QDateTime::currentDateTime().date().year() + 1), "dd.MM.yyyy hh:mm") << 60;
|
|
QTest::newRow("dateTime - yearly - new year") << QDateTime::fromString(QString("31.12.%1 23:00").arg(QDateTime::currentDateTime().date().year() + 1), "dd.MM.yyyy hh:mm") << 120;
|
|
QTest::newRow("dateTime - yearly - valentines day") << QDateTime::fromString("14.02.2017 08:00", "dd.MM.yyyy hh:mm") << 120;
|
|
}
|
|
|
|
void TestTimeManager::testCalendarYearlyDateTime()
|
|
{
|
|
QFETCH(QDateTime, dateTime);
|
|
QFETCH(int, duration);
|
|
|
|
initTimeManager();
|
|
|
|
// Action (without params)
|
|
QVariantMap ruleMap; QVariantMap action; QVariantMap exitAction;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
// Exit action (with params)
|
|
QVariantList actionParams;
|
|
QVariantMap param1;
|
|
param1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId);
|
|
param1.insert("value", 12);
|
|
actionParams.append(param1);
|
|
QVariantMap param2;
|
|
param2.insert("paramTypeId", mockWithParamsActionParam2ParamTypeId);
|
|
param2.insert("value", true);
|
|
actionParams.append(param2);
|
|
exitAction.insert("actionTypeId", mockWithParamsActionTypeId);
|
|
exitAction.insert("deviceId", m_mockDeviceId);
|
|
exitAction.insert("ruleActionParams", actionParams);
|
|
|
|
// RepeatingOption
|
|
QVariantMap repeatingOption;
|
|
repeatingOption.insert("mode", "RepeatingModeYearly");
|
|
|
|
// CalendarItem
|
|
QVariantMap calendarItem;
|
|
calendarItem.insert("datetime", QVariant(dateTime.toTime_t()));
|
|
calendarItem.insert("duration", QVariant(duration));
|
|
calendarItem.insert("repeating", repeatingOption);
|
|
|
|
// Create the rule map
|
|
ruleMap.insert("name", "Time based yearly calendar rule");
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorCalendar(calendarItem));
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("exitActions", QVariantList() << exitAction);
|
|
|
|
// Add the rule
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QDateTime oneMinuteBeforeEvent = dateTime.addSecs(-60);
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(oneMinuteBeforeEvent);
|
|
verifyRuleNotExecuted();
|
|
// active
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
cleanupMockHistory();
|
|
// active unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(duration * 30));
|
|
verifyRuleNotExecuted();
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(duration * 60));
|
|
verifyRuleExecuted(mockWithParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
cleanupMockHistory();
|
|
// inactive unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs((duration + 1) * 60));
|
|
verifyRuleNotExecuted();
|
|
|
|
|
|
// One year "Back to the future"
|
|
oneMinuteBeforeEvent = oneMinuteBeforeEvent.addYears(1);
|
|
dateTime = dateTime.addYears(1);
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(oneMinuteBeforeEvent);
|
|
verifyRuleNotExecuted();
|
|
// active
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
cleanupMockHistory();
|
|
// active unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(duration * 30));
|
|
verifyRuleNotExecuted();
|
|
// inactive
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(duration * 60));
|
|
verifyRuleExecuted(mockWithParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
|
|
// inactive unchanged
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs((duration + 1) * 60));
|
|
verifyRuleNotExecuted();
|
|
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemStates_data()
|
|
{
|
|
initTimeManager();
|
|
|
|
// Repeating option
|
|
QVariantMap repeatingOptionDaily;
|
|
repeatingOptionDaily.insert("mode", "RepeatingModeDaily");
|
|
|
|
// Action
|
|
QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
// Exit action (with params)
|
|
QVariantMap exitAction;
|
|
QVariantList actionParams;
|
|
QVariantMap param1;
|
|
param1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId);
|
|
param1.insert("value", 12);
|
|
actionParams.append(param1);
|
|
QVariantMap param2;
|
|
param2.insert("paramTypeId", mockWithParamsActionParam2ParamTypeId);
|
|
param2.insert("value", true);
|
|
actionParams.append(param2);
|
|
exitAction.insert("actionTypeId", mockWithParamsActionTypeId);
|
|
exitAction.insert("deviceId", m_mockDeviceId);
|
|
exitAction.insert("ruleActionParams", actionParams);
|
|
|
|
// Stateevaluators
|
|
QVariantMap stateEvaluator;
|
|
QVariantMap stateDescriptorInt;
|
|
stateDescriptorInt.insert("deviceId", m_mockDeviceId);
|
|
stateDescriptorInt.insert("operator", enumValueName(Types::ValueOperatorGreaterOrEqual));
|
|
stateDescriptorInt.insert("stateTypeId", mockIntStateTypeId);
|
|
stateDescriptorInt.insert("value", 65);
|
|
QVariantMap stateDescriptorBool;
|
|
stateDescriptorBool.insert("deviceId", m_mockDeviceId);
|
|
stateDescriptorBool.insert("operator", enumValueName(Types::ValueOperatorEquals));
|
|
stateDescriptorBool.insert("stateTypeId", mockBoolStateTypeId);
|
|
stateDescriptorBool.insert("value", true);
|
|
QVariantMap stateEvaluatorInt;
|
|
stateEvaluatorInt.insert("stateDescriptor", stateDescriptorInt);
|
|
stateEvaluatorInt.insert("operator", enumValueName(Types::StateOperatorAnd));
|
|
QVariantMap stateEvaluatorBool;
|
|
stateEvaluatorBool.insert("stateDescriptor", stateDescriptorBool);
|
|
stateEvaluatorBool.insert("operator", enumValueName(Types::StateOperatorAnd));
|
|
QVariantList childEvaluators;
|
|
childEvaluators.append(stateEvaluatorInt);
|
|
childEvaluators.append(stateEvaluatorBool);
|
|
stateEvaluator.insert("childEvaluators", childEvaluators);
|
|
stateEvaluator.insert("operator", enumValueName(Types::StateOperatorAnd));
|
|
|
|
|
|
// The rule
|
|
QVariantMap ruleMap;
|
|
ruleMap.insert("name", "Time and state based daily calendar rule");
|
|
ruleMap.insert("stateEvaluator", stateEvaluator);
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("exitActions", QVariantList() << exitAction);
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorCalendar(createCalendarItem("08:00", 10, repeatingOptionDaily)));
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(07,59)));
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
|
|
QTest::addColumn<QDateTime>("dateTime");
|
|
QTest::addColumn<bool>("boolValue");
|
|
QTest::addColumn<int>("intValue");
|
|
QTest::addColumn<bool>("trigger");
|
|
QTest::addColumn<bool>("active");
|
|
|
|
QTest::newRow("07:59 | true - 66") << QDateTime(QDate::currentDate(), QTime(07,59)) << true << 66 << false << false;
|
|
QTest::newRow("08:00 | true - 66") << QDateTime(QDate::currentDate(), QTime(8,0)) << true << 66 << true << true;
|
|
QTest::newRow("08:01 | true - 66") << QDateTime(QDate::currentDate(), QTime(8,1)) << true << 66 << false << false;
|
|
QTest::newRow("08:02 | false - 66") << QDateTime(QDate::currentDate(), QTime(8,2)) << false << 66 << true << false;
|
|
QTest::newRow("08:03 | true - 65") << QDateTime(QDate::currentDate(), QTime(8,3)) << true << 65 << true << true;
|
|
QTest::newRow("08:06 | true - 64") << QDateTime(QDate::currentDate(), QTime(8,6)) << true << 64 << true << false;
|
|
QTest::newRow("08:07 | false - 64") << QDateTime(QDate::currentDate(), QTime(8,7)) << false << 64 << false << false;
|
|
QTest::newRow("08:07 | false - 65") << QDateTime(QDate::currentDate(), QTime(8,7)) << false << 65 << false << false;
|
|
QTest::newRow("08:08 | true - 65") << QDateTime(QDate::currentDate(), QTime(8,8)) << true << 65 << true << true;
|
|
QTest::newRow("08:09 | true - 65") << QDateTime(QDate::currentDate(), QTime(8,9)) << true << 65 << false << false;
|
|
QTest::newRow("08:10 | true - 65") << QDateTime(QDate::currentDate(), QTime(8,10)) << true << 65 << true << false;
|
|
QTest::newRow("08:11 | true - 65") << QDateTime(QDate::currentDate(), QTime(8,11)) << true << 65 << false << false;
|
|
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemStates()
|
|
{
|
|
QFETCH(QDateTime, dateTime);
|
|
QFETCH(bool, boolValue);
|
|
QFETCH(int, intValue);
|
|
QFETCH(bool, trigger);
|
|
QFETCH(bool, active);
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
setBoolState(boolValue);
|
|
setIntState(intValue);
|
|
|
|
// Actions
|
|
if (trigger && active) {
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
}
|
|
|
|
// Exit actions
|
|
if (trigger && !active) {
|
|
verifyRuleExecuted(mockWithParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
}
|
|
|
|
// Nothing triggert
|
|
if (!trigger) {
|
|
verifyRuleNotExecuted();
|
|
}
|
|
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemEvent_data()
|
|
{
|
|
initTimeManager();
|
|
|
|
// Action (without params)
|
|
QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
QVariantMap eventDescriptor;
|
|
eventDescriptor.insert("eventTypeId", mockEvent1EventTypeId);
|
|
eventDescriptor.insert("deviceId", m_mockDeviceId);
|
|
|
|
// The rule
|
|
QVariantMap ruleMap;
|
|
ruleMap.insert("name", "Time and state based daily calendar rule");
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("eventDescriptors", QVariantList() << eventDescriptor);
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorCalendar(createCalendarItem("08:00", 10)));
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(7,59)));
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QVariantMap params;
|
|
params.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
printJson(response);
|
|
|
|
|
|
QTest::addColumn<QDateTime>("dateTime");
|
|
QTest::addColumn<bool>("trigger");
|
|
|
|
QTest::newRow("07:59 | not trigger") << QDateTime(QDate::currentDate(), QTime(07,59)) << false;
|
|
QTest::newRow("08:00 | trigger") << QDateTime(QDate::currentDate(), QTime(8,0)) << true;
|
|
QTest::newRow("08:05 | trigger") << QDateTime(QDate::currentDate(), QTime(8,5)) << true;
|
|
QTest::newRow("08:10 | not trigger") << QDateTime(QDate::currentDate(), QTime(8,10)) << false;
|
|
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemEvent()
|
|
{
|
|
QFETCH(QDateTime, dateTime);
|
|
QFETCH(bool, trigger);
|
|
|
|
cleanupMockHistory();
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
|
|
// Trigger event
|
|
triggerMockEvent1();
|
|
|
|
if (trigger) {
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
} else {
|
|
verifyRuleNotExecuted();
|
|
}
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemStatesEvent_data()
|
|
{
|
|
initTimeManager();
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(7,59)));
|
|
|
|
// Action (without params)
|
|
QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
// Event descriptor
|
|
QVariantMap eventDescriptor;
|
|
eventDescriptor.insert("eventTypeId", mockEvent1EventTypeId);
|
|
eventDescriptor.insert("deviceId", m_mockDeviceId);
|
|
|
|
// State evaluator
|
|
QVariantMap stateDescriptorBool;
|
|
stateDescriptorBool.insert("deviceId", m_mockDeviceId);
|
|
stateDescriptorBool.insert("operator", enumValueName(Types::ValueOperatorEquals));
|
|
stateDescriptorBool.insert("stateTypeId", mockBoolStateTypeId);
|
|
stateDescriptorBool.insert("value", true);
|
|
|
|
QVariantMap stateEvaluator;
|
|
stateEvaluator.insert("stateDescriptor", stateDescriptorBool);
|
|
|
|
// The rule
|
|
QVariantMap ruleMap;
|
|
ruleMap.insert("name", "Time and state and event based daily calendar rule");
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("eventDescriptors", QVariantList() << eventDescriptor);
|
|
ruleMap.insert("stateEvaluator", stateEvaluator);
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorCalendar(createCalendarItem("08:00", 10)));
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QVariantMap params;
|
|
params.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
|
|
QTest::addColumn<QDateTime>("dateTime");
|
|
QTest::addColumn<bool>("boolValue");
|
|
QTest::addColumn<bool>("trigger");
|
|
|
|
QTest::newRow("07:59 | state true | not trigger") << QDateTime(QDate::currentDate(), QTime(07,59)) << true << false;
|
|
QTest::newRow("08:00 | state true | trigger") << QDateTime(QDate::currentDate(), QTime(8,0)) << true << true;
|
|
QTest::newRow("08:01 | state false | not trigger") << QDateTime(QDate::currentDate(), QTime(8,1)) << false << false;
|
|
QTest::newRow("08:02 | state true | trigger") << QDateTime(QDate::currentDate(), QTime(8,2)) << true << true;
|
|
QTest::newRow("08:10 | state true | not trigger") << QDateTime(QDate::currentDate(), QTime(8,10)) << true << false;
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemStatesEvent()
|
|
{
|
|
QFETCH(QDateTime, dateTime);
|
|
QFETCH(bool, boolValue);
|
|
QFETCH(bool, trigger);
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
setBoolState(boolValue);
|
|
|
|
// Trigger event
|
|
triggerMockEvent1();
|
|
|
|
if (trigger) {
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
} else {
|
|
verifyRuleNotExecuted();
|
|
}
|
|
}
|
|
|
|
void TestTimeManager::testCalendarItemCrossesMidnight()
|
|
{
|
|
initTimeManager();
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(20,00)));
|
|
|
|
// Action
|
|
QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
QVariantMap repeatingOptionDaily;
|
|
repeatingOptionDaily.insert("mode", "RepeatingModeDaily");
|
|
|
|
// The rule
|
|
QVariantMap ruleMap;
|
|
ruleMap.insert("name", "Time based from 23:00 to 01:00");
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorCalendar(createCalendarItem("23:00", 120, repeatingOptionDaily)));
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QVariantMap params;
|
|
params.insert("ruleId", ruleId);
|
|
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
QVERIFY2(response.toMap().value("params").toMap().value("rule").toMap().value("active").toBool() == false, "Rule is active while it should not be (20:00)");
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(22,59)));
|
|
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
QVERIFY2(response.toMap().value("params").toMap().value("rule").toMap().value("active").toBool() == false, "Rule is active while it should not be (22:59)");
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(23,00)));
|
|
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
QVERIFY2(response.toMap().value("params").toMap().value("rule").toMap().value("active").toBool() == true, "Rule is not active while it should be (23:00)");
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(23,10)));
|
|
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
QVERIFY2(response.toMap().value("params").toMap().value("rule").toMap().value("active").toBool() == true, "Rule is not active while it should be (23:10)");
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(00,00)));
|
|
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
QVERIFY2(response.toMap().value("params").toMap().value("rule").toMap().value("active").toBool() == true, "Rule is not active while it should be (00:00)");
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(00,30)));
|
|
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
QVERIFY2(response.toMap().value("params").toMap().value("rule").toMap().value("active").toBool() == true, "Rule is not active while it should be (00:30)");
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(01,00)));
|
|
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
QVERIFY2(response.toMap().value("params").toMap().value("rule").toMap().value("active").toBool() == false, "Rule is active while it should not be (01:00)");
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(02,00)));
|
|
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
QVERIFY2(response.toMap().value("params").toMap().value("rule").toMap().value("active").toBool() == false, "Rule is active while it should not be (02:00)");
|
|
|
|
}
|
|
|
|
void TestTimeManager::testEventBasedWithCalendarItemCrossingMidnight()
|
|
{
|
|
initTimeManager();
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(20,00)));
|
|
|
|
// Event descriptor
|
|
QVariantMap eventDescriptor;
|
|
eventDescriptor.insert("eventTypeId", mockEvent1EventTypeId);
|
|
eventDescriptor.insert("deviceId", m_mockDeviceId);
|
|
|
|
// Action
|
|
QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
QVariantMap repeatingOptionDaily;
|
|
repeatingOptionDaily.insert("mode", "RepeatingModeDaily");
|
|
|
|
// The rule
|
|
QVariantMap ruleMap;
|
|
ruleMap.insert("name", "Time based from 23:00 to 01:00");
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("eventDescriptors", QVariantList() << eventDescriptor);
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorCalendar(createCalendarItem("23:00", 120, repeatingOptionDaily)));
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QVariantMap params;
|
|
params.insert("ruleId", ruleId);
|
|
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
QVERIFY2(response.toMap().value("params").toMap().value("rule").toMap().value("id").toUuid() == ruleId, "Rule not found in GetRules");
|
|
|
|
cleanupMockHistory();
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(20, 00)));
|
|
triggerMockEvent1();
|
|
verifyRuleNotExecuted();
|
|
|
|
cleanupMockHistory();
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(23, 00)));
|
|
triggerMockEvent1();
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
|
|
cleanupMockHistory();
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(23, 50)));
|
|
triggerMockEvent1();
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
|
|
cleanupMockHistory();
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(00, 00)));
|
|
triggerMockEvent1();
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
|
|
cleanupMockHistory();
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(01, 00)));
|
|
triggerMockEvent1();
|
|
verifyRuleNotExecuted();
|
|
}
|
|
|
|
void TestTimeManager::testEventItemDateTime_data()
|
|
{
|
|
QTest::addColumn<QDateTime>("dateTime");
|
|
|
|
QTest::newRow("dateTime - christmas") << QDateTime::fromString("24.12.2016 20:00", "dd.MM.yyyy hh:mm");
|
|
QTest::newRow("dateTime - new year") << QDateTime::fromString("31.12.2016 00:00", "dd.MM.yyyy hh:mm");
|
|
QTest::newRow("dateTime - valentines day") << QDateTime::fromString("14.02.2016 08:00", "dd.MM.yyyy hh:mm");
|
|
}
|
|
|
|
void TestTimeManager::testEventItemDateTime()
|
|
{
|
|
QFETCH(QDateTime, dateTime);
|
|
|
|
initTimeManager();
|
|
|
|
// Action (without params)
|
|
QVariantMap ruleMap; QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
// Create the rule map
|
|
ruleMap.insert("name", "Time based hourly calendar rule");
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorTimeEvent(createTimeEventItem(dateTime.toTime_t())));
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
|
|
// Add the rule
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(-120));
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(-60));
|
|
verifyRuleNotExecuted();
|
|
|
|
// trigger
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(60));
|
|
verifyRuleNotExecuted();
|
|
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::testEventItemHourly_data()
|
|
{
|
|
QTest::addColumn<QTime>("time");
|
|
|
|
QTest::newRow("timeEvent - houly 08:10") << QTime(8,10);
|
|
QTest::newRow("timeEvent - houly 12:33") << QTime(12,33);
|
|
}
|
|
|
|
void TestTimeManager::testEventItemHourly()
|
|
{
|
|
QFETCH(QTime, time);
|
|
|
|
initTimeManager();
|
|
|
|
// Repeating option
|
|
QVariantMap repeatingOptionHourly;
|
|
repeatingOptionHourly.insert("mode", "RepeatingModeHourly");
|
|
|
|
// Action
|
|
QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
QVariantMap ruleMap;
|
|
ruleMap.insert("name", "Time based hourly event rule");
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorTimeEvent(createTimeEventItem(time.toString("hh:mm"), repeatingOptionHourly)));
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QVariantMap params;
|
|
params.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
|
|
QDateTime currentDateTime = NymeaCore::instance()->timeManager()->currentDateTime();
|
|
QDateTime beforeEventDateTime = QDateTime(currentDateTime.date(), time.addSecs(-60));
|
|
|
|
// check the next 24 hours in 8h steps
|
|
for (int i = 0; i < 24; i+=8) {
|
|
// Back to the future (8h)
|
|
beforeEventDateTime = beforeEventDateTime.addSecs(i * 60 * 60);
|
|
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime);
|
|
verifyRuleNotExecuted();
|
|
// trigger
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime.addSecs(60));
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime.addSecs(120));
|
|
verifyRuleNotExecuted();
|
|
cleanupMockHistory();
|
|
}
|
|
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::testEventItemDaily_data()
|
|
{
|
|
QTest::addColumn<QTime>("time");
|
|
QTest::addColumn<bool>("withRepeatingOption");
|
|
|
|
QTest::newRow("timeEvent - daily 10:01") << QTime(10,1) << false;
|
|
QTest::newRow("timeEvent - daily 22:22") << QTime(22,22) << true;
|
|
}
|
|
|
|
void TestTimeManager::testEventItemDaily()
|
|
{
|
|
QFETCH(QTime, time);
|
|
QFETCH(bool, withRepeatingOption);
|
|
|
|
initTimeManager();
|
|
|
|
// Repeating option
|
|
QVariantMap repeatingOptionDaily;
|
|
repeatingOptionDaily.insert("mode", "RepeatingModeDaily");
|
|
|
|
// Action
|
|
QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
QVariantMap ruleMap;
|
|
ruleMap.insert("name", "Time based daily event rule");
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
if (withRepeatingOption) {
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorTimeEvent(createTimeEventItem(time.toString("hh:mm"), repeatingOptionDaily)));
|
|
} else {
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorTimeEvent(createTimeEventItem(time.toString("hh:mm"))));
|
|
}
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QVariantMap params;
|
|
params.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
|
|
QDateTime currentDateTime = NymeaCore::instance()->timeManager()->currentDateTime();
|
|
QDateTime beforeEventDateTime = QDateTime(currentDateTime.date(), time.addSecs(-60));
|
|
|
|
// check the next 2 days
|
|
for (int i = 0; i < 2; i++) {
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime);
|
|
verifyRuleNotExecuted();
|
|
// trigger
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime.addSecs(60));
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime.addSecs(120));
|
|
verifyRuleNotExecuted();
|
|
|
|
// Back to the future (1 day)
|
|
beforeEventDateTime = beforeEventDateTime.addDays(1);
|
|
}
|
|
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::testEventItemWeekly_data()
|
|
{
|
|
QTest::addColumn<QTime>("time");
|
|
QTest::addColumn<QVariantList>("weekDays");
|
|
|
|
QTest::newRow("timeEvent - houly 08:10") << QTime(8,10) << (QVariantList() << 6 << 7);
|
|
QTest::newRow("timeEvent - houly 12:33") << QTime(12,33) << (QVariantList() << 2 << 4 << 7);
|
|
}
|
|
|
|
void TestTimeManager::testEventItemWeekly()
|
|
{
|
|
QFETCH(QTime, time);
|
|
QFETCH(QVariantList, weekDays);
|
|
|
|
initTimeManager();
|
|
|
|
// Repeating option
|
|
QVariantMap repeatingOptionWeekly;
|
|
repeatingOptionWeekly.insert("mode", "RepeatingModeWeekly");
|
|
repeatingOptionWeekly.insert("weekDays", weekDays);
|
|
|
|
// Action
|
|
QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
QVariantMap ruleMap;
|
|
ruleMap.insert("name", "Time based daily event rule");
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorTimeEvent(createTimeEventItem(time.toString("hh:mm"), repeatingOptionWeekly)));
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QVariantMap params;
|
|
params.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
|
|
QDateTime currentDateTime = NymeaCore::instance()->timeManager()->currentDateTime();
|
|
QDateTime beforeEventDateTime = QDateTime(currentDateTime.date(), time.addSecs(-60));
|
|
|
|
QList<int> allowedDays;
|
|
foreach (const QVariant &weekDayVariant, weekDays) {
|
|
allowedDays.append(weekDayVariant.toInt());
|
|
}
|
|
|
|
// check the next 7 days
|
|
for (int i = 0; i < 7; i++) {
|
|
// check if today is one of the weekdays
|
|
if (allowedDays.contains(beforeEventDateTime.date().dayOfWeek())) {
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime);
|
|
verifyRuleNotExecuted();
|
|
// trigger
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime.addSecs(60));
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime.addSecs(120));
|
|
verifyRuleNotExecuted();
|
|
|
|
} else {
|
|
// not triggering on this weekday
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime.addSecs(60));
|
|
verifyRuleNotExecuted();
|
|
}
|
|
|
|
// Back to the future (1 day)
|
|
beforeEventDateTime = beforeEventDateTime.addDays(1);
|
|
}
|
|
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::testEventItemMonthly_data()
|
|
{
|
|
QTest::addColumn<QTime>("time");
|
|
QTest::addColumn<QVariantList>("monthDays");
|
|
|
|
QTest::newRow("timeEvent - houly 08:10") << QTime(8,10) << (QVariantList() << 1 << 12 << 17 << 19 << 31);
|
|
QTest::newRow("timeEvent - houly 12:33") << QTime(12,33) << (QVariantList() << 2 << 4 << 7 << 30);
|
|
}
|
|
|
|
void TestTimeManager::testEventItemMonthly()
|
|
{
|
|
QFETCH(QTime, time);
|
|
QFETCH(QVariantList, monthDays);
|
|
|
|
initTimeManager();
|
|
|
|
// Repeating option
|
|
QVariantMap repeatingOptionMonthly;
|
|
repeatingOptionMonthly.insert("mode", "RepeatingModeMonthly");
|
|
repeatingOptionMonthly.insert("monthDays", monthDays);
|
|
|
|
// Action
|
|
QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
QVariantMap ruleMap;
|
|
ruleMap.insert("name", "Time based daily event rule");
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorTimeEvent(createTimeEventItem(time.toString("hh:mm"), repeatingOptionMonthly)));
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QVariantMap params;
|
|
params.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
|
|
QDateTime currentDateTime = NymeaCore::instance()->timeManager()->currentDateTime();
|
|
QDateTime beforeEventDateTime = QDateTime(currentDateTime.date(), time.addSecs(-60));
|
|
|
|
QList<int> allowedDays;
|
|
foreach (const QVariant &monthDayVariant, monthDays) {
|
|
allowedDays.append(monthDayVariant.toInt());
|
|
}
|
|
|
|
// check the next 7 days
|
|
for (int i = 0; i < 31; i++) {
|
|
// check if today is one of the month days
|
|
if (allowedDays.contains(beforeEventDateTime.date().day())) {
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime);
|
|
verifyRuleNotExecuted();
|
|
// trigger
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime.addSecs(60));
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime.addSecs(120));
|
|
verifyRuleNotExecuted();
|
|
} else {
|
|
// not triggering on this weekday
|
|
NymeaCore::instance()->timeManager()->setTime(beforeEventDateTime.addSecs(60));
|
|
verifyRuleNotExecuted();
|
|
}
|
|
|
|
// Back to the future (1 day)
|
|
beforeEventDateTime = beforeEventDateTime.addDays(1);
|
|
}
|
|
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::testEventItemYearly_data()
|
|
{
|
|
QTest::addColumn<QDateTime>("dateTime");
|
|
|
|
QTest::newRow("dateTime - christmas") << QDateTime::fromString("24.12.2016 20:00", "dd.MM.yyyy hh:mm");
|
|
QTest::newRow("dateTime - new year") << QDateTime::fromString("31.12.2016 00:00", "dd.MM.yyyy hh:mm");
|
|
QTest::newRow("dateTime - valentines day") << QDateTime::fromString("14.02.2016 08:00", "dd.MM.yyyy hh:mm");
|
|
}
|
|
|
|
void TestTimeManager::testEventItemYearly()
|
|
{
|
|
QFETCH(QDateTime, dateTime);
|
|
|
|
initTimeManager();
|
|
|
|
// Repeating option
|
|
QVariantMap repeatingOptionYearly;
|
|
repeatingOptionYearly.insert("mode", "RepeatingModeYearly");
|
|
|
|
// Action (without params)
|
|
QVariantMap ruleMap; QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
// Create the rule map
|
|
ruleMap.insert("name", "Time based hourly calendar rule");
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorTimeEvent(createTimeEventItem(dateTime.toTime_t(), repeatingOptionYearly)));
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
|
|
// Add the rule
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
// Tick now, one minute before, on time, one minute after
|
|
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(-60));
|
|
verifyRuleNotExecuted();
|
|
// trigger
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(60));
|
|
verifyRuleNotExecuted();
|
|
|
|
// Tick next year, one minute before, on time, one minute after
|
|
QDateTime nextYear = dateTime.addYears(1);
|
|
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(nextYear.addSecs(-60));
|
|
verifyRuleNotExecuted();
|
|
// trigger
|
|
NymeaCore::instance()->timeManager()->setTime(nextYear);
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(nextYear.addSecs(60));
|
|
verifyRuleNotExecuted();
|
|
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
|
|
void TestTimeManager::testEventItemStates_data()
|
|
{
|
|
initTimeManager();
|
|
|
|
NymeaCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(7,59)));
|
|
|
|
// Action (without params)
|
|
QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
// Time descriptor
|
|
QVariantMap timeEventItem1 = createTimeEventItem("08:00");
|
|
QVariantMap timeEventItem2 = createTimeEventItem("09:00");
|
|
QVariantMap timeDescriptor;
|
|
timeDescriptor.insert("timeEventItems", QVariantList() << timeEventItem1 << timeEventItem2);
|
|
|
|
// State evaluator
|
|
QVariantMap stateDescriptorBool;
|
|
stateDescriptorBool.insert("deviceId", m_mockDeviceId);
|
|
stateDescriptorBool.insert("operator", enumValueName(Types::ValueOperatorEquals));
|
|
stateDescriptorBool.insert("stateTypeId", mockBoolStateTypeId);
|
|
stateDescriptorBool.insert("value", true);
|
|
|
|
QVariantMap stateEvaluator;
|
|
stateEvaluator.insert("stateDescriptor", stateDescriptorBool);
|
|
|
|
// The rule
|
|
QVariantMap ruleMap;
|
|
ruleMap.insert("name", "Time and state and event based daily calendar rule");
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("stateEvaluator", stateEvaluator);
|
|
ruleMap.insert("timeDescriptor", timeDescriptor);
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
QVariantMap params;
|
|
params.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
|
|
|
QTest::addColumn<QDateTime>("dateTime");
|
|
QTest::addColumn<bool>("boolValue");
|
|
QTest::addColumn<bool>("trigger");
|
|
|
|
QTest::newRow("TimeEvent 07:59 | state false | not trigger") << QDateTime(QDate::currentDate(), QTime(7,59)) << false << false;
|
|
QTest::newRow("TimeEvent 07:59 | state true | not trigger") << QDateTime(QDate::currentDate(), QTime(7,59)) << true << false;
|
|
QTest::newRow("TimeEvent 08:00 | state false | not trigger") << QDateTime(QDate::currentDate(), QTime(8,0)) << false << false;
|
|
QTest::newRow("TimeEvent 07:59 | state true | not trigger") << QDateTime(QDate::currentDate(), QTime(7,59)) << true << false;
|
|
QTest::newRow("TimeEvent 08:00 | state true | trigger") << QDateTime(QDate::currentDate(), QTime(8,0)) << true << true;
|
|
QTest::newRow("TimeEvent 08:01 | state true | not trigger") << QDateTime(QDate::currentDate(), QTime(8,1)) << true << false;
|
|
QTest::newRow("TimeEvent 08:01 | state false | not trigger") << QDateTime(QDate::currentDate(), QTime(8,1)) << true << false;
|
|
QTest::newRow("TimeEvent 08:30 | state true | not trigger") << QDateTime(QDate::currentDate(), QTime(8,30)) << true << false;
|
|
QTest::newRow("TimeEvent 09:00 | state true | trigger") << QDateTime(QDate::currentDate(), QTime(9,0)) << true << true;
|
|
QTest::newRow("TimeEvent 09:01 | state true | not trigger") << QDateTime(QDate::currentDate(), QTime(9,1)) << true << false;
|
|
}
|
|
|
|
void TestTimeManager::testEventItemStates()
|
|
{
|
|
QFETCH(QDateTime, dateTime);
|
|
QFETCH(bool, boolValue);
|
|
QFETCH(bool, trigger);
|
|
|
|
// Set state
|
|
setBoolState(boolValue);
|
|
|
|
// Set time
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
|
|
if (trigger) {
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
} else {
|
|
verifyRuleNotExecuted();
|
|
}
|
|
}
|
|
|
|
|
|
void TestTimeManager::testEnableDisableTimeRule()
|
|
{
|
|
initTimeManager();
|
|
QDateTime dateTime(QDate::currentDate(), QTime(10,15));
|
|
|
|
// Repeating option
|
|
QVariantMap repeatingOptionDaily;
|
|
repeatingOptionDaily.insert("mode", "RepeatingModeDaily");
|
|
|
|
// Action
|
|
QVariantMap action;
|
|
action.insert("actionTypeId", mockWithoutParamsActionTypeId);
|
|
action.insert("deviceId", m_mockDeviceId);
|
|
action.insert("ruleActionParams", QVariantList());
|
|
|
|
QVariantMap ruleMap;
|
|
ruleMap.insert("name", "Time based daily event rule");
|
|
ruleMap.insert("actions", QVariantList() << action);
|
|
ruleMap.insert("timeDescriptor", createTimeDescriptorTimeEvent(createTimeEventItem(dateTime.time().toString("hh:mm"), repeatingOptionDaily)));
|
|
|
|
|
|
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
|
|
verifyRuleError(response);
|
|
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
|
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(-2));
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(-1));
|
|
verifyRuleNotExecuted();
|
|
// trigger
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
// not triggering
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(1));
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(2));
|
|
verifyRuleNotExecuted();
|
|
|
|
|
|
// Now DISABLE the rule
|
|
QVariantMap enableDisableParams;
|
|
enableDisableParams.insert("ruleId", ruleId.toString());
|
|
response = injectAndWait("Rules.DisableRule", enableDisableParams);
|
|
verifyRuleError(response);
|
|
|
|
// trigger
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(-1));
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
verifyRuleNotExecuted();
|
|
|
|
// Now ENABLE the rule again
|
|
response.clear();
|
|
response = injectAndWait("Rules.EnableRule", enableDisableParams);
|
|
verifyRuleError(response);
|
|
|
|
// trigger
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime.addSecs(-1));
|
|
NymeaCore::instance()->timeManager()->setTime(dateTime);
|
|
verifyRuleExecuted(mockWithoutParamsActionTypeId);
|
|
cleanupMockHistory();
|
|
|
|
// REMOVE rule
|
|
QVariantMap removeParams;
|
|
removeParams.insert("ruleId", ruleId);
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
|
|
void TestTimeManager::initTimeManager()
|
|
{
|
|
cleanupMockHistory();
|
|
removeAllRules();
|
|
enableNotifications({"Rules", "Devices", "Events"});
|
|
NymeaCore::instance()->timeManager()->stopTimer();
|
|
qDebug() << NymeaCore::instance()->timeManager()->currentDateTime().toString();
|
|
}
|
|
|
|
void TestTimeManager::verifyRuleExecuted(const ActionTypeId &actionTypeId)
|
|
{
|
|
// Verify rule got executed
|
|
QNetworkAccessManager nam;
|
|
QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*)));
|
|
QNetworkRequest request(QUrl(QString("http://localhost:%1/actionhistory").arg(QString::number(m_mockDevice1Port))));
|
|
QNetworkReply *reply = nam.get(request);
|
|
spy.wait();
|
|
QCOMPARE(spy.count(), 1);
|
|
|
|
QByteArray actionHistory = reply->readAll();
|
|
QVERIFY2(actionTypeId == ActionTypeId(actionHistory), "Action not triggered");
|
|
reply->deleteLater();
|
|
}
|
|
|
|
void TestTimeManager::verifyRuleNotExecuted()
|
|
{
|
|
QNetworkAccessManager nam;
|
|
QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*)));
|
|
QNetworkRequest request(QUrl(QString("http://localhost:%1/actionhistory").arg(QString::number(m_mockDevice1Port))));
|
|
QNetworkReply *reply = nam.get(request);
|
|
spy.wait();
|
|
QCOMPARE(spy.count(), 1);
|
|
|
|
QByteArray actionHistory = reply->readAll();
|
|
QVERIFY2(actionHistory.isEmpty(), "Actfdsfadsion is triggered while it should not have been.");
|
|
reply->deleteLater();
|
|
}
|
|
|
|
void TestTimeManager::cleanupMockHistory() {
|
|
QNetworkAccessManager nam;
|
|
QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*)));
|
|
QNetworkRequest request(QUrl(QString("http://localhost:%1/clearactionhistory").arg(QString::number(m_mockDevice1Port))));
|
|
QNetworkReply *reply = nam.get(request);
|
|
spy.wait();
|
|
QCOMPARE(spy.count(), 1);
|
|
reply->deleteLater();
|
|
}
|
|
|
|
void TestTimeManager::removeAllRules()
|
|
{
|
|
qDebug() << "Remove all rules";
|
|
QVariant response = injectAndWait("Rules.GetRules");
|
|
QVariantList ruleDescriptions = response.toMap().value("params").toMap().value("ruleDescriptions").toList();
|
|
QVariantMap removeParams;
|
|
foreach (const QVariant &ruleDescription, ruleDescriptions) {
|
|
removeParams.insert("ruleId", ruleDescription.toMap().value("id"));
|
|
response = injectAndWait("Rules.RemoveRule", removeParams);
|
|
verifyRuleError(response);
|
|
}
|
|
}
|
|
|
|
void TestTimeManager::setIntState(const int &value)
|
|
{
|
|
qDebug() << "Setting mock int state to" << value;
|
|
|
|
QVariantMap params;
|
|
params.insert("deviceId", m_mockDeviceId);
|
|
params.insert("stateTypeId", mockIntStateTypeId);
|
|
QVariant response = injectAndWait("Devices.GetStateValue", params);
|
|
verifyError(response, "deviceError", "DeviceErrorNoError");
|
|
|
|
int currentStateValue = response.toMap().value("params").toMap().value("value").toInt();
|
|
bool shouldGetNotification = currentStateValue != value;
|
|
|
|
QNetworkAccessManager nam;
|
|
QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*)));
|
|
QSignalSpy stateSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
|
|
|
|
spy.clear();
|
|
QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(mockIntStateTypeId.toString()).arg(value)));
|
|
QNetworkReply *reply = nam.get(request);
|
|
spy.wait();
|
|
QCOMPARE(spy.count(), 1);
|
|
reply->deleteLater();
|
|
|
|
if (shouldGetNotification) {
|
|
stateSpy.wait(100);
|
|
// Wait for state changed notification
|
|
QVariantList stateChangedVariants = checkNotifications(stateSpy, "Devices.StateChanged");
|
|
QVERIFY2(stateChangedVariants.count() == 1, "Did not get Devices.StateChanged notification.");
|
|
|
|
QVariantMap notification = stateChangedVariants.first().toMap().value("params").toMap();
|
|
QVERIFY2(notification.contains("deviceId"), "Devices.StateChanged notification does not contain deviceId");
|
|
QVERIFY2(DeviceId(notification.value("deviceId").toString()) == m_mockDeviceId, "Devices.StateChanged notification does not contain the correct deviceId");
|
|
QVERIFY2(notification.contains("stateTypeId"), "Devices.StateChanged notification does not contain stateTypeId");
|
|
QVERIFY2(StateTypeId(notification.value("stateTypeId").toString()) == mockIntStateTypeId, "Devices.StateChanged notification does not contain the correct stateTypeId");
|
|
QVERIFY2(notification.contains("value"), "Devices.StateChanged notification does not contain new state value");
|
|
QVERIFY2(notification.value("value").toInt() == value, "Devices.StateChanged notification does not contain the new value");
|
|
}
|
|
}
|
|
|
|
void TestTimeManager::setBoolState(const bool &value)
|
|
{
|
|
qCDebug(dcTests()) << "Setting mock bool state to" << value;
|
|
|
|
// Get the current state value to check if we have to wait for state changed notfication
|
|
QVariantMap params;
|
|
params.insert("deviceId", m_mockDeviceId);
|
|
params.insert("stateTypeId", mockBoolStateTypeId);
|
|
QVariant response = injectAndWait("Devices.GetStateValue", params);
|
|
verifyError(response, "deviceError", "DeviceErrorNoError");
|
|
|
|
bool currentStateValue = response.toMap().value("params").toMap().value("value").toBool();
|
|
bool shouldGetNotification = currentStateValue != value;
|
|
|
|
QNetworkAccessManager nam;
|
|
QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*)));
|
|
QSignalSpy stateSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
|
|
|
|
QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(mockBoolStateTypeId.toString()).arg(value)));
|
|
QNetworkReply *reply = nam.get(request);
|
|
spy.wait();
|
|
QCOMPARE(spy.count(), 1);
|
|
reply->deleteLater();
|
|
|
|
if (shouldGetNotification) {
|
|
stateSpy.wait(100);
|
|
// Wait for state changed notification
|
|
QVariantList stateChangedSignals = checkNotifications(stateSpy, "Devices.StateChanged");
|
|
QCOMPARE(stateChangedSignals.count(), 1);
|
|
|
|
QVariantMap notification = stateChangedSignals.first().toMap().value("params").toMap();
|
|
QVERIFY2(notification.contains("deviceId"), "Devices.StateChanged notification does not contain deviceId");
|
|
QVERIFY2(DeviceId(notification.value("deviceId").toString()) == m_mockDeviceId, "Devices.StateChanged notification does not contain the correct deviceId");
|
|
QVERIFY2(notification.contains("stateTypeId"), "Devices.StateChanged notification does not contain stateTypeId");
|
|
QVERIFY2(StateTypeId(notification.value("stateTypeId").toString()) == mockBoolStateTypeId, "Devices.StateChanged notification does not contain the correct stateTypeId");
|
|
QVERIFY2(notification.contains("value"), "Devices.StateChanged notification does not contain new state value");
|
|
QVERIFY2(notification.value("value").toBool() == value, "Devices.StateChanged notification does not contain the new value");
|
|
}
|
|
}
|
|
|
|
void TestTimeManager::triggerMockEvent1()
|
|
{
|
|
qDebug() << "Trigger mock event 1";
|
|
|
|
QNetworkAccessManager nam;
|
|
QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*)));
|
|
|
|
QSignalSpy eventSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
|
|
|
|
QNetworkRequest request(QUrl(QString("http://localhost:%1/generateevent?eventtypeid=%2").arg(m_mockDevice1Port).arg(mockEvent1EventTypeId.toString())));
|
|
QNetworkReply *reply = nam.get(request);
|
|
spy.wait();
|
|
QCOMPARE(spy.count(), 1);
|
|
reply->deleteLater();
|
|
|
|
if (eventSpy.isEmpty()) {
|
|
eventSpy.wait();
|
|
}
|
|
QVariantList eventTriggerVariants = checkNotifications(eventSpy, "Events.EventTriggered");
|
|
QVERIFY2(eventTriggerVariants.count() == 1, "Did not get Events.EventTriggered notification.");
|
|
QVERIFY2(eventTriggerVariants.first().toMap().value("params").toMap().contains("event"), "Notification Events.EventTriggered does not contain event.");
|
|
QVariantMap eventMap = eventTriggerVariants.first().toMap().value("params").toMap().value("event").toMap();
|
|
|
|
QVERIFY2(eventMap.contains("deviceId"), "Events.EventTriggered notification does not contain deviceId");
|
|
QVERIFY2(DeviceId(eventMap.value("deviceId").toString()) == m_mockDeviceId, "Events.EventTriggered notification does not contain the correct deviceId");
|
|
QVERIFY2(eventMap.contains("eventTypeId"), "Events.EventTriggered notification does not contain eventTypeId");
|
|
QVERIFY2(EventTypeId(eventMap.value("eventTypeId").toString()) == mockEvent1EventTypeId, "Events.EventTriggered notification does not contain the correct eventTypeId");
|
|
}
|
|
|
|
QVariantMap TestTimeManager::createTimeEventItem(const QString &time, const QVariantMap &repeatingOption) const
|
|
{
|
|
QVariantMap calendarItem;
|
|
calendarItem.insert("time", time);
|
|
if (!repeatingOption.isEmpty())
|
|
calendarItem.insert("repeating", repeatingOption);
|
|
|
|
return calendarItem;
|
|
}
|
|
|
|
QVariantMap TestTimeManager::createTimeEventItem(const int &dateTime, const QVariantMap &repeatingOption) const
|
|
{
|
|
QVariantMap calendarItem;
|
|
calendarItem.insert("datetime", dateTime);
|
|
if (!repeatingOption.isEmpty())
|
|
calendarItem.insert("repeating", repeatingOption);
|
|
|
|
return calendarItem;
|
|
}
|
|
|
|
QVariantMap TestTimeManager::createTimeDescriptorTimeEvent(const QVariantMap &timeEventItem) const
|
|
{
|
|
QVariantMap timeDescriptorTimeEvent;
|
|
timeDescriptorTimeEvent.insert("timeEventItems", QVariantList() << timeEventItem);
|
|
return timeDescriptorTimeEvent;
|
|
}
|
|
|
|
QVariantMap TestTimeManager::createTimeDescriptorTimeEvent(const QVariantList &timeEventItems) const
|
|
{
|
|
QVariantMap timeDescriptorTimeEvent;
|
|
timeDescriptorTimeEvent.insert("timeEventItems", timeEventItems);
|
|
return timeDescriptorTimeEvent;
|
|
}
|
|
|
|
QVariantMap TestTimeManager::createCalendarItem(const QString &time, const uint &duration, const QVariantMap &repeatingOption) const
|
|
{
|
|
QVariantMap calendarItem;
|
|
calendarItem.insert("startTime", time);
|
|
calendarItem.insert("duration", duration);
|
|
if (!repeatingOption.isEmpty())
|
|
calendarItem.insert("repeating", repeatingOption);
|
|
|
|
return calendarItem;
|
|
}
|
|
|
|
QVariantMap TestTimeManager::createCalendarItem(const int &dateTime, const uint &duration, const QVariantMap &repeatingOption) const
|
|
{
|
|
QVariantMap calendarItem;
|
|
calendarItem.insert("datetime", dateTime);
|
|
calendarItem.insert("duration", duration);
|
|
if (!repeatingOption.isEmpty())
|
|
calendarItem.insert("repeating", repeatingOption);
|
|
|
|
return calendarItem;
|
|
}
|
|
|
|
QVariantMap TestTimeManager::createTimeDescriptorCalendar(const QVariantMap &calendarItem) const
|
|
{
|
|
QVariantMap timeDescriptorCalendar;
|
|
timeDescriptorCalendar.insert("calendarItems", QVariantList() << calendarItem);
|
|
return timeDescriptorCalendar;
|
|
}
|
|
|
|
QVariantMap TestTimeManager::createTimeDescriptorCalendar(const QVariantList &calendarItems) const
|
|
{
|
|
QVariantMap timeDescriptorCalendar;
|
|
timeDescriptorCalendar.insert("calendarItems", calendarItems);
|
|
return timeDescriptorCalendar;
|
|
}
|
|
|
|
#include "testtimemanager.moc"
|
|
QTEST_MAIN(TestTimeManager)
|